Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: content/browser/compositor/reflector_impl.cc

Issue 228083002: Make ReflectorImpl use mailboxes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/compositor/reflector_impl.h" 5 #include "content/browser/compositor/reflector_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "content/browser/compositor/browser_compositor_output_surface.h" 9 #include "content/browser/compositor/browser_compositor_output_surface.h"
10 #include "content/browser/compositor/owned_mailbox.h"
10 #include "content/common/gpu/client/gl_helper.h" 11 #include "content/common/gpu/client/gl_helper.h"
11 #include "ui/compositor/layer.h" 12 #include "ui/compositor/layer.h"
12 13
13 namespace content { 14 namespace content {
14 15
15 ReflectorImpl::ReflectorImpl( 16 ReflectorImpl::ReflectorImpl(
16 ui::Compositor* mirrored_compositor, 17 ui::Compositor* mirrored_compositor,
17 ui::Layer* mirroring_layer, 18 ui::Layer* mirroring_layer,
18 IDMap<BrowserCompositorOutputSurface>* output_surface_map, 19 IDMap<BrowserCompositorOutputSurface>* output_surface_map,
19 int surface_id) 20 int surface_id)
20 : texture_id_(0), 21 : impl_unsafe_(output_surface_map),
21 texture_size_(mirrored_compositor->size()), 22 main_unsafe_(mirrored_compositor, mirroring_layer),
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()), 23 impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
27 main_message_loop_(base::MessageLoopProxy::current()), 24 main_message_loop_(base::MessageLoopProxy::current()),
28 surface_id_(surface_id) { 25 surface_id_(surface_id) {
26 GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
27 MainThreadData& main = GetMain();
28 main.mailbox = new OwnedMailbox(helper);
29 impl_message_loop_->PostTask( 29 impl_message_loop_->PostTask(
30 FROM_HERE, 30 FROM_HERE,
31 base::Bind(&ReflectorImpl::InitOnImplThread, this)); 31 base::Bind(
32 } 32 &ReflectorImpl::InitOnImplThread, this, main.mailbox->holder()));
33 33 }
34 void ReflectorImpl::InitOnImplThread() { 34
35 ReflectorImpl::MainThreadData::MainThreadData(
36 ui::Compositor* mirrored_compositor,
37 ui::Layer* mirroring_layer)
38 : needs_set_mailbox(true),
39 mirrored_compositor(mirrored_compositor),
40 mirroring_layer(mirroring_layer) {}
41
42 ReflectorImpl::MainThreadData::~MainThreadData() {}
43
44 ReflectorImpl::ImplThreadData::ImplThreadData(
45 IDMap<BrowserCompositorOutputSurface>* output_surface_map)
46 : output_surface_map(output_surface_map),
47 output_surface(NULL),
48 texture_id(0) {}
49
50 ReflectorImpl::ImplThreadData::~ImplThreadData() {}
51
52 ReflectorImpl::ImplThreadData& ReflectorImpl::GetImpl() {
53 DCHECK(impl_message_loop_->BelongsToCurrentThread());
54 return impl_unsafe_;
55 }
56
57 ReflectorImpl::MainThreadData& ReflectorImpl::GetMain() {
58 DCHECK(main_message_loop_->BelongsToCurrentThread());
59 return main_unsafe_;
60 }
61
62 void ReflectorImpl::InitOnImplThread(const gpu::MailboxHolder& mailbox_holder) {
63 ImplThreadData& impl = GetImpl();
35 // Ignore if the reflector was shutdown before 64 // Ignore if the reflector was shutdown before
36 // initialized, or it's already initialized. 65 // initialized, or it's already initialized.
37 if (!output_surface_map_ || gl_helper_.get()) 66 if (!impl.output_surface_map || impl.gl_helper.get())
38 return; 67 return;
68
69 impl.mailbox_holder = mailbox_holder;
39 70
40 BrowserCompositorOutputSurface* source_surface = 71 BrowserCompositorOutputSurface* source_surface =
41 output_surface_map_->Lookup(surface_id_); 72 impl.output_surface_map->Lookup(surface_id_);
42 // Skip if the source surface isn't ready yet. This will be 73 // Skip if the source surface isn't ready yet. This will be
43 // initiailze when the source surface becomes ready. 74 // initialized when the source surface becomes ready.
44 if (!source_surface) 75 if (!source_surface)
45 return; 76 return;
46 77
47 AttachToOutputSurfaceOnImplThread(source_surface); 78 AttachToOutputSurfaceOnImplThread(impl.mailbox_holder, source_surface);
48 // The shared texture doesn't have the data, so invokes full redraw 79 }
49 // now. 80
81 void ReflectorImpl::OnSourceSurfaceReady(
82 BrowserCompositorOutputSurface* source_surface) {
83 ImplThreadData& impl = GetImpl();
84 AttachToOutputSurfaceOnImplThread(impl.mailbox_holder, source_surface);
85 }
86
87 void ReflectorImpl::Shutdown() {
88 MainThreadData& main = GetMain();
89 main.mailbox = NULL;
90 main.mirroring_layer->SetShowPaintedContent();
91 main.mirroring_layer = NULL;
92 impl_message_loop_->PostTask(
93 FROM_HERE, base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
94 }
95
96 void ReflectorImpl::DetachFromOutputSurface() {
97 ImplThreadData& impl = GetImpl();
98 DCHECK(impl.output_surface);
99 impl.output_surface->SetReflector(NULL);
100 DCHECK(impl.texture_id);
101 impl.gl_helper->DeleteTexture(impl.texture_id);
102 impl.texture_id = 0;
103 impl.gl_helper.reset();
104 impl.output_surface = NULL;
105 }
106
107 void ReflectorImpl::ShutdownOnImplThread() {
108 ImplThreadData& impl = GetImpl();
109 if (impl.output_surface)
110 DetachFromOutputSurface();
111 impl.output_surface_map = NULL;
112 // The instance must be deleted on main thread.
113 main_message_loop_->PostTask(FROM_HERE,
114 base::Bind(&ReflectorImpl::DeleteOnMainThread,
115 scoped_refptr<ReflectorImpl>(this)));
116 }
117
118 void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
119 BrowserCompositorOutputSurface* output_surface) {
120 MainThreadData& main = GetMain();
121 GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
122 main.mailbox = new OwnedMailbox(helper);
123 main.needs_set_mailbox = true;
124 main.mirroring_layer->SetShowPaintedContent();
125 impl_message_loop_->PostTask(
126 FROM_HERE,
127 base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
128 this,
129 main.mailbox->holder(),
130 output_surface));
131 }
132
133 void ReflectorImpl::OnMirroringCompositorResized() {
134 MainThreadData& main = GetMain();
135 main.mirroring_layer->SchedulePaint(main.mirroring_layer->bounds());
136 }
137
138 void ReflectorImpl::OnSwapBuffers() {
139 ImplThreadData& impl = GetImpl();
140 gfx::Size size = impl.output_surface->SurfaceSize();
141 if (impl.texture_id) {
142 impl.gl_helper->CopyTextureFullImage(impl.texture_id, size);
143 impl.gl_helper->Flush();
144 }
145 main_message_loop_->PostTask(
146 FROM_HERE,
147 base::Bind(
148 &ReflectorImpl::FullRedrawOnMainThread, this->AsWeakPtr(), size));
149 }
150
151 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
152 ImplThreadData& impl = GetImpl();
153 if (impl.texture_id) {
154 impl.gl_helper->CopyTextureSubImage(impl.texture_id, rect);
155 impl.gl_helper->Flush();
156 }
157 main_message_loop_->PostTask(
158 FROM_HERE,
159 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
160 this->AsWeakPtr(),
161 impl.output_surface->SurfaceSize(),
162 rect));
163 }
164
165 ReflectorImpl::~ReflectorImpl() {
166 // Make sure the reflector is deleted on main thread.
167 DCHECK_EQ(main_message_loop_.get(), base::MessageLoopProxy::current().get());
168 }
169
170 static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox,
171 unsigned int sync_point,
172 bool is_lost) {
173 mailbox->UpdateSyncPoint(sync_point);
174 }
175
176 void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
177 const gpu::MailboxHolder& mailbox_holder,
178 BrowserCompositorOutputSurface* output_surface) {
179 ImplThreadData& impl = GetImpl();
180 if (output_surface == impl.output_surface)
181 return;
182 if (impl.output_surface)
183 DetachFromOutputSurface();
184 impl.output_surface = output_surface;
185 output_surface->context_provider()->BindToCurrentThread();
186 impl.gl_helper.reset(
187 new GLHelper(output_surface->context_provider()->ContextGL(),
188 output_surface->context_provider()->ContextSupport()));
189 impl.texture_id = impl.gl_helper->ConsumeMailboxToTexture(
190 mailbox_holder.mailbox, mailbox_holder.sync_point);
191 impl.gl_helper->ResizeTexture(impl.texture_id, output_surface->SurfaceSize());
192 impl.gl_helper->Flush();
193 output_surface->SetReflector(this);
194 // The texture doesn't have the data, so invokes full redraw now.
50 main_message_loop_->PostTask( 195 main_message_loop_->PostTask(
51 FROM_HERE, 196 FROM_HERE,
52 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread, 197 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
53 scoped_refptr<ReflectorImpl>(this))); 198 scoped_refptr<ReflectorImpl>(this)));
54 } 199 }
55 200
56 void ReflectorImpl::OnSourceSurfaceReady(int surface_id) { 201 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
57 DCHECK_EQ(surface_id_, surface_id); 202 MainThreadData& main = GetMain();
58 InitOnImplThread(); 203 if (!main.mirroring_layer || !main.mailbox ||
59 } 204 main.mailbox->mailbox().IsZero())
60 205 return;
61 void ReflectorImpl::Shutdown() { 206 if (main.needs_set_mailbox) {
62 mirroring_compositor_ = NULL; 207 main.mirroring_layer->SetTextureMailbox(
63 mirroring_layer_ = NULL; 208 cc::TextureMailbox(main.mailbox->holder()),
64 { 209 cc::SingleReleaseCallback::Create(
65 base::AutoLock lock(texture_lock_); 210 base::Bind(ReleaseMailbox, main.mailbox)),
66 texture_id_ = 0; 211 size);
212 main.needs_set_mailbox = false;
213 } else {
214 main.mirroring_layer->SetTextureSize(size);
67 } 215 }
68 shared_texture_ = NULL; 216 main.mirroring_layer->SetBounds(gfx::Rect(size));
69 impl_message_loop_->PostTask(
70 FROM_HERE,
71 base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
72 }
73
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)));
86 }
87
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));
94 }
95
96 void ReflectorImpl::OnMirroringCompositorResized() {
97 mirroring_compositor_->ScheduleFullRedraw();
98 }
99
100 void ReflectorImpl::OnLostResources() {
101 mirroring_layer_->SetShowPaintedContent();
102 }
103
104 void ReflectorImpl::OnReshape(gfx::Size size) {
105 if (texture_size_ == size)
106 return;
107 texture_size_ = size;
108 {
109 base::AutoLock lock(texture_lock_);
110 if (texture_id_) {
111 gl_helper_->ResizeTexture(texture_id_, size);
112 gl_helper_->Flush();
113 }
114 }
115 main_message_loop_->PostTask(
116 FROM_HERE,
117 base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread,
118 this->AsWeakPtr(),
119 texture_size_));
120 }
121
122 void ReflectorImpl::OnSwapBuffers() {
123 {
124 base::AutoLock lock(texture_lock_);
125 if (texture_id_) {
126 gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
127 gl_helper_->Flush();
128 }
129 }
130 main_message_loop_->PostTask(
131 FROM_HERE,
132 base::Bind(&ReflectorImpl::FullRedrawOnMainThread,
133 this->AsWeakPtr(),
134 texture_size_));
135 }
136
137 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
138 {
139 base::AutoLock lock(texture_lock_);
140 if (texture_id_) {
141 gl_helper_->CopyTextureSubImage(texture_id_, rect);
142 gl_helper_->Flush();
143 }
144 }
145 main_message_loop_->PostTask(
146 FROM_HERE,
147 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
148 this->AsWeakPtr(),
149 texture_size_,
150 rect));
151 }
152
153 void ReflectorImpl::CreateSharedTextureOnMainThread(gfx::Size size) {
154 {
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_);
161 ImageTransportFactory::GetInstance()->GetGLHelper()->Flush();
162 }
163 mirroring_layer_->SetExternalTexture(shared_texture_.get());
164 FullRedrawOnMainThread(size);
165 }
166
167 ReflectorImpl::~ReflectorImpl() {
168 // Make sure the reflector is deleted on main thread.
169 DCHECK_EQ(main_message_loop_.get(),
170 base::MessageLoopProxy::current().get());
171 }
172
173 void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
174 BrowserCompositorOutputSurface* output_surface) {
175 output_surface->context_provider()->BindToCurrentThread();
176 gl_helper_.reset(
177 new GLHelper(output_surface->context_provider()->ContextGL(),
178 output_surface->context_provider()->ContextSupport()));
179 output_surface->SetReflector(this);
180 main_message_loop_->PostTask(
181 FROM_HERE,
182 base::Bind(&ReflectorImpl::CreateSharedTextureOnMainThread,
183 this->AsWeakPtr(),
184 texture_size_));
185 }
186
187 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
188 if (!mirroring_layer_)
189 return;
190 mirroring_layer_->SetBounds(gfx::Rect(size));
191 } 217 }
192 218
193 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) { 219 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
194 if (!mirroring_compositor_) 220 MainThreadData& main = GetMain();
221 if (!main.mirroring_layer)
195 return; 222 return;
196 UpdateTextureSizeOnMainThread(size); 223 UpdateTextureSizeOnMainThread(size);
197 mirroring_compositor_->ScheduleFullRedraw(); 224 main.mirroring_layer->SchedulePaint(main.mirroring_layer->bounds());
198 } 225 }
199 226
200 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size, 227 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
201 gfx::Rect rect) { 228 gfx::Rect rect) {
202 if (!mirroring_compositor_) 229 MainThreadData& main = GetMain();
230 if (!main.mirroring_layer)
203 return; 231 return;
204 UpdateTextureSizeOnMainThread(size); 232 UpdateTextureSizeOnMainThread(size);
205 // Flip the coordinates to compositor's one. 233 // Flip the coordinates to compositor's one.
206 int y = size.height() - rect.y() - rect.height(); 234 int y = size.height() - rect.y() - rect.height();
207 gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height()); 235 gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
208 mirroring_layer_->SchedulePaint(new_rect); 236 main.mirroring_layer->SchedulePaint(new_rect);
209 } 237 }
210 238
211 void ReflectorImpl::FullRedrawContentOnMainThread() { 239 void ReflectorImpl::FullRedrawContentOnMainThread() {
212 mirrored_compositor_->ScheduleFullRedraw(); 240 MainThreadData& main = GetMain();
241 main.mirrored_compositor->ScheduleFullRedraw();
213 } 242 }
214 243
215 } // namespace content 244 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/compositor/reflector_impl.h ('k') | content/browser/renderer_host/render_widget_host_view_aura.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698