1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/aura/reflector_impl.h"
8 #include "base/location.h"
9 #include "content/browser/aura/browser_compositor_output_surface.h"
10 #include "content/common/gpu/client/gl_helper.h"
11 #include "ui/compositor/layer.h"
15 ReflectorImpl::ReflectorImpl(
16 ui::Compositor
* mirrored_compositor
,
17 ui::Layer
* mirroring_layer
,
18 IDMap
<BrowserCompositorOutputSurface
>* output_surface_map
,
21 texture_size_(mirrored_compositor
->size()),
22 output_surface_map_(output_surface_map
),
23 mirrored_compositor_(mirrored_compositor
),
24 mirroring_compositor_(mirroring_layer
->GetCompositor()),
25 mirroring_layer_(mirroring_layer
),
26 impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
27 main_message_loop_(base::MessageLoopProxy::current()),
28 surface_id_(surface_id
) {
29 CreateSharedTexture();
30 impl_message_loop_
->PostTask(
32 base::Bind(&ReflectorImpl::InitOnImplThread
, this));
35 void ReflectorImpl::InitOnImplThread() {
36 // Ignore if the reflector was shutdown before
37 // initialized, or it's already initialized.
38 if (!output_surface_map_
|| gl_helper_
.get())
41 BrowserCompositorOutputSurface
* source_surface
=
42 output_surface_map_
->Lookup(surface_id_
);
43 // Skip if the source surface isn't ready yet. This will be
44 // initiailze when the source surface becomes ready.
48 AttachToOutputSurface(source_surface
);
49 gl_helper_
->CopyTextureFullImage(texture_id_
, texture_size_
);
50 // The shared texture doesn't have the data, so invokes full redraw
52 main_message_loop_
->PostTask(
54 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread
,
55 scoped_refptr
<ReflectorImpl
>(this)));
58 void ReflectorImpl::OnSourceSurfaceReady(int surface_id
) {
59 DCHECK_EQ(surface_id_
, surface_id
);
63 void ReflectorImpl::Shutdown() {
64 mirroring_compositor_
= NULL
;
65 mirroring_layer_
= NULL
;
66 shared_texture_
= NULL
;
67 impl_message_loop_
->PostTask(
69 base::Bind(&ReflectorImpl::ShutdownOnImplThread
, this));
72 void ReflectorImpl::ShutdownOnImplThread() {
73 BrowserCompositorOutputSurface
* output_surface
=
74 output_surface_map_
->Lookup(surface_id_
);
76 output_surface
->SetReflector(NULL
);
77 output_surface_map_
= NULL
;
79 // The instance must be deleted on main thread.
80 main_message_loop_
->PostTask(
82 base::Bind(&ReflectorImpl::DeleteOnMainThread
,
83 scoped_refptr
<ReflectorImpl
>(this)));
86 // This must be called on ImplThread, or before the surface is passed to
88 void ReflectorImpl::AttachToOutputSurface(
89 BrowserCompositorOutputSurface
* output_surface
) {
91 new GLHelper(output_surface
->context_provider()->ContextGL(),
92 output_surface
->context_provider()->ContextSupport()));
93 output_surface
->SetReflector(this);
96 void ReflectorImpl::OnMirroringCompositorResized() {
97 mirroring_compositor_
->ScheduleFullRedraw();
100 void ReflectorImpl::OnLostResources() {
101 shared_texture_
= NULL
;
102 mirroring_layer_
->SetShowPaintedContent();
105 void ReflectorImpl::OnReshape(gfx::Size size
) {
106 if (texture_size_
== size
)
108 texture_size_
= size
;
110 gl_helper_
->ResizeTexture(texture_id_
, size
);
111 main_message_loop_
->PostTask(
113 base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread
,
118 void ReflectorImpl::OnSwapBuffers() {
120 gl_helper_
->CopyTextureFullImage(texture_id_
, texture_size_
);
121 main_message_loop_
->PostTask(
123 base::Bind(&ReflectorImpl::FullRedrawOnMainThread
,
128 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect
) {
130 gl_helper_
->CopyTextureSubImage(texture_id_
, rect
);
131 main_message_loop_
->PostTask(
133 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread
,
139 void ReflectorImpl::CreateSharedTexture() {
141 ImageTransportFactory::GetInstance()->GetGLHelper()->CreateTexture();
143 ImageTransportFactory::GetInstance()->CreateOwnedTexture(
144 texture_size_
, 1.0f
, texture_id_
);
145 mirroring_layer_
->SetExternalTexture(shared_texture_
.get());
148 ReflectorImpl::~ReflectorImpl() {
149 // Make sure the reflector is deleted on main thread.
150 DCHECK_EQ(main_message_loop_
.get(),
151 base::MessageLoopProxy::current().get());
154 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size
) {
155 if (!mirroring_layer_
)
157 mirroring_layer_
->SetBounds(gfx::Rect(size
));
160 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size
) {
161 if (!mirroring_compositor_
)
163 UpdateTextureSizeOnMainThread(size
);
164 mirroring_compositor_
->ScheduleFullRedraw();
167 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size
,
169 if (!mirroring_compositor_
)
171 UpdateTextureSizeOnMainThread(size
);
172 // Flip the coordinates to compositor's one.
173 int y
= size
.height() - rect
.y() - rect
.height();
174 gfx::Rect
new_rect(rect
.x(), y
, rect
.width(), rect
.height());
175 mirroring_layer_
->SchedulePaint(new_rect
);
178 void ReflectorImpl::FullRedrawContentOnMainThread() {
179 mirrored_compositor_
->ScheduleFullRedraw();
182 } // namespace content