This source file includes following definitions.
- surface_id_
- InitOnImplThread
- OnSourceSurfaceReady
- Shutdown
- ShutdownOnImplThread
- ReattachToOutputSurfaceFromMainThread
- OnMirroringCompositorResized
- OnLostResources
- OnReshape
- OnSwapBuffers
- OnPostSubBuffer
- CreateSharedTextureOnMainThread
- AttachToOutputSurfaceOnImplThread
- UpdateTextureSizeOnMainThread
- FullRedrawOnMainThread
- UpdateSubBufferOnMainThread
- FullRedrawContentOnMainThread
#include "content/browser/compositor/reflector_impl.h"
#include "base/bind.h"
#include "base/location.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/common/gpu/client/gl_helper.h"
#include "ui/compositor/layer.h"
namespace content {
ReflectorImpl::ReflectorImpl(
ui::Compositor* mirrored_compositor,
ui::Layer* mirroring_layer,
IDMap<BrowserCompositorOutputSurface>* output_surface_map,
int surface_id)
: texture_id_(0),
texture_size_(mirrored_compositor->size()),
output_surface_map_(output_surface_map),
mirrored_compositor_(mirrored_compositor),
mirroring_compositor_(mirroring_layer->GetCompositor()),
mirroring_layer_(mirroring_layer),
impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
main_message_loop_(base::MessageLoopProxy::current()),
surface_id_(surface_id) {
impl_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::InitOnImplThread, this));
}
void ReflectorImpl::InitOnImplThread() {
if (!output_surface_map_ || gl_helper_.get())
return;
BrowserCompositorOutputSurface* source_surface =
output_surface_map_->Lookup(surface_id_);
if (!source_surface)
return;
AttachToOutputSurfaceOnImplThread(source_surface);
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
scoped_refptr<ReflectorImpl>(this)));
}
void ReflectorImpl::OnSourceSurfaceReady(int surface_id) {
DCHECK_EQ(surface_id_, surface_id);
InitOnImplThread();
}
void ReflectorImpl::Shutdown() {
mirroring_compositor_ = NULL;
mirroring_layer_ = NULL;
{
base::AutoLock lock(texture_lock_);
texture_id_ = 0;
}
shared_texture_ = NULL;
impl_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
}
void ReflectorImpl::ShutdownOnImplThread() {
BrowserCompositorOutputSurface* output_surface =
output_surface_map_->Lookup(surface_id_);
if (output_surface)
output_surface->SetReflector(NULL);
output_surface_map_ = NULL;
gl_helper_.reset();
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::DeleteOnMainThread,
scoped_refptr<ReflectorImpl>(this)));
}
void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
BrowserCompositorOutputSurface* output_surface) {
impl_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
this, output_surface));
}
void ReflectorImpl::OnMirroringCompositorResized() {
mirroring_compositor_->ScheduleFullRedraw();
}
void ReflectorImpl::OnLostResources() {
mirroring_layer_->SetShowPaintedContent();
}
void ReflectorImpl::OnReshape(gfx::Size size) {
if (texture_size_ == size)
return;
texture_size_ = size;
{
base::AutoLock lock(texture_lock_);
if (texture_id_) {
gl_helper_->ResizeTexture(texture_id_, size);
gl_helper_->Flush();
}
}
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread,
this->AsWeakPtr(),
texture_size_));
}
void ReflectorImpl::OnSwapBuffers() {
{
base::AutoLock lock(texture_lock_);
if (texture_id_) {
gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
gl_helper_->Flush();
}
}
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::FullRedrawOnMainThread,
this->AsWeakPtr(),
texture_size_));
}
void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
{
base::AutoLock lock(texture_lock_);
if (texture_id_) {
gl_helper_->CopyTextureSubImage(texture_id_, rect);
gl_helper_->Flush();
}
}
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
this->AsWeakPtr(),
texture_size_,
rect));
}
void ReflectorImpl::CreateSharedTextureOnMainThread(gfx::Size size) {
{
base::AutoLock lock(texture_lock_);
texture_id_ =
ImageTransportFactory::GetInstance()->GetGLHelper()->CreateTexture();
shared_texture_ =
ImageTransportFactory::GetInstance()->CreateOwnedTexture(
size, 1.0f, texture_id_);
ImageTransportFactory::GetInstance()->GetGLHelper()->Flush();
}
mirroring_layer_->SetExternalTexture(shared_texture_.get());
FullRedrawOnMainThread(size);
}
ReflectorImpl::~ReflectorImpl() {
DCHECK_EQ(main_message_loop_.get(),
base::MessageLoopProxy::current().get());
}
void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
BrowserCompositorOutputSurface* output_surface) {
output_surface->context_provider()->BindToCurrentThread();
gl_helper_.reset(
new GLHelper(output_surface->context_provider()->ContextGL(),
output_surface->context_provider()->ContextSupport()));
output_surface->SetReflector(this);
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::CreateSharedTextureOnMainThread,
this->AsWeakPtr(),
texture_size_));
}
void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
if (!mirroring_layer_)
return;
mirroring_layer_->SetBounds(gfx::Rect(size));
}
void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
if (!mirroring_compositor_)
return;
UpdateTextureSizeOnMainThread(size);
mirroring_compositor_->ScheduleFullRedraw();
}
void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
gfx::Rect rect) {
if (!mirroring_compositor_)
return;
UpdateTextureSizeOnMainThread(size);
int y = size.height() - rect.y() - rect.height();
gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
mirroring_layer_->SchedulePaint(new_rect);
}
void ReflectorImpl::FullRedrawContentOnMainThread() {
mirrored_compositor_->ScheduleFullRedraw();
}
}