Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / compositor / reflector_impl.cc
blob82ddc709cd52a3363358b8d8b9d2ee973edc7da5
1 // Copyright 2014 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/compositor/reflector_impl.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "content/browser/compositor/browser_compositor_output_surface.h"
10 #include "content/common/gpu/client/gl_helper.h"
11 #include "ui/compositor/layer.h"
13 namespace content {
15 ReflectorImpl::ReflectorImpl(
16 ui::Compositor* mirrored_compositor,
17 ui::Layer* mirroring_layer,
18 IDMap<BrowserCompositorOutputSurface>* output_surface_map,
19 int surface_id)
20 : texture_id_(0),
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 impl_message_loop_->PostTask(
30 FROM_HERE,
31 base::Bind(&ReflectorImpl::InitOnImplThread, this));
34 void ReflectorImpl::InitOnImplThread() {
35 // Ignore if the reflector was shutdown before
36 // initialized, or it's already initialized.
37 if (!output_surface_map_ || gl_helper_.get())
38 return;
40 BrowserCompositorOutputSurface* source_surface =
41 output_surface_map_->Lookup(surface_id_);
42 // Skip if the source surface isn't ready yet. This will be
43 // initiailze when the source surface becomes ready.
44 if (!source_surface)
45 return;
47 AttachToOutputSurfaceOnImplThread(source_surface);
48 // The shared texture doesn't have the data, so invokes full redraw
49 // now.
50 main_message_loop_->PostTask(
51 FROM_HERE,
52 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
53 scoped_refptr<ReflectorImpl>(this)));
56 void ReflectorImpl::OnSourceSurfaceReady(int surface_id) {
57 DCHECK_EQ(surface_id_, surface_id);
58 InitOnImplThread();
61 void ReflectorImpl::Shutdown() {
62 mirroring_compositor_ = NULL;
63 mirroring_layer_ = NULL;
65 base::AutoLock lock(texture_lock_);
66 texture_id_ = 0;
68 shared_texture_ = NULL;
69 impl_message_loop_->PostTask(
70 FROM_HERE,
71 base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
74 void ReflectorImpl::ShutdownOnImplThread() {
75 BrowserCompositorOutputSurface* output_surface =
76 output_surface_map_->Lookup(surface_id_);
77 if (output_surface)
78 output_surface->SetReflector(NULL);
79 output_surface_map_ = NULL;
80 gl_helper_.reset();
81 // The instance must be deleted on main thread.
82 main_message_loop_->PostTask(
83 FROM_HERE,
84 base::Bind(&ReflectorImpl::DeleteOnMainThread,
85 scoped_refptr<ReflectorImpl>(this)));
88 void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
89 BrowserCompositorOutputSurface* output_surface) {
90 impl_message_loop_->PostTask(
91 FROM_HERE,
92 base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
93 this, output_surface));
96 void ReflectorImpl::OnMirroringCompositorResized() {
97 mirroring_compositor_->ScheduleFullRedraw();
100 void ReflectorImpl::OnLostResources() {
101 mirroring_layer_->SetShowPaintedContent();
104 void ReflectorImpl::OnReshape(gfx::Size size) {
105 if (texture_size_ == size)
106 return;
107 texture_size_ = size;
109 base::AutoLock lock(texture_lock_);
110 if (texture_id_) {
111 gl_helper_->ResizeTexture(texture_id_, size);
112 gl_helper_->Flush();
115 main_message_loop_->PostTask(
116 FROM_HERE,
117 base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread,
118 this->AsWeakPtr(),
119 texture_size_));
122 void ReflectorImpl::OnSwapBuffers() {
124 base::AutoLock lock(texture_lock_);
125 if (texture_id_) {
126 gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
127 gl_helper_->Flush();
130 main_message_loop_->PostTask(
131 FROM_HERE,
132 base::Bind(&ReflectorImpl::FullRedrawOnMainThread,
133 this->AsWeakPtr(),
134 texture_size_));
137 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
139 base::AutoLock lock(texture_lock_);
140 if (texture_id_) {
141 gl_helper_->CopyTextureSubImage(texture_id_, rect);
142 gl_helper_->Flush();
145 main_message_loop_->PostTask(
146 FROM_HERE,
147 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
148 this->AsWeakPtr(),
149 texture_size_,
150 rect));
153 void ReflectorImpl::CreateSharedTextureOnMainThread(gfx::Size size) {
155 base::AutoLock lock(texture_lock_);
156 texture_id_ =
157 ImageTransportFactory::GetInstance()->GetGLHelper()->CreateTexture();
158 shared_texture_ =
159 ImageTransportFactory::GetInstance()->CreateOwnedTexture(
160 size, 1.0f, texture_id_);
162 mirroring_layer_->SetExternalTexture(shared_texture_.get());
163 FullRedrawOnMainThread(size);
166 ReflectorImpl::~ReflectorImpl() {
167 // Make sure the reflector is deleted on main thread.
168 DCHECK_EQ(main_message_loop_.get(),
169 base::MessageLoopProxy::current().get());
172 void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
173 BrowserCompositorOutputSurface* output_surface) {
174 output_surface->context_provider()->BindToCurrentThread();
175 gl_helper_.reset(
176 new GLHelper(output_surface->context_provider()->ContextGL(),
177 output_surface->context_provider()->ContextSupport()));
178 output_surface->SetReflector(this);
179 main_message_loop_->PostTask(
180 FROM_HERE,
181 base::Bind(&ReflectorImpl::CreateSharedTextureOnMainThread,
182 this->AsWeakPtr(),
183 texture_size_));
186 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
187 if (!mirroring_layer_)
188 return;
189 mirroring_layer_->SetBounds(gfx::Rect(size));
192 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
193 if (!mirroring_compositor_)
194 return;
195 UpdateTextureSizeOnMainThread(size);
196 mirroring_compositor_->ScheduleFullRedraw();
199 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
200 gfx::Rect rect) {
201 if (!mirroring_compositor_)
202 return;
203 UpdateTextureSizeOnMainThread(size);
204 // Flip the coordinates to compositor's one.
205 int y = size.height() - rect.y() - rect.height();
206 gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
207 mirroring_layer_->SchedulePaint(new_rect);
210 void ReflectorImpl::FullRedrawContentOnMainThread() {
211 mirrored_compositor_->ScheduleFullRedraw();
214 } // namespace content