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

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: 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 : output_surface_map_(output_surface_map),
21 texture_size_(mirrored_compositor->size()), 22 output_surface_(NULL),
22 output_surface_map_(output_surface_map), 23 impl_thread_texture_id_(0),
24 needs_set_mailbox_(true),
23 mirrored_compositor_(mirrored_compositor), 25 mirrored_compositor_(mirrored_compositor),
24 mirroring_compositor_(mirroring_layer->GetCompositor()),
25 mirroring_layer_(mirroring_layer), 26 mirroring_layer_(mirroring_layer),
26 impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()), 27 impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
27 main_message_loop_(base::MessageLoopProxy::current()), 28 main_message_loop_(base::MessageLoopProxy::current()),
28 surface_id_(surface_id) { 29 surface_id_(surface_id) {
29 impl_message_loop_->PostTask( 30 GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
30 FROM_HERE, 31 main_thread_mailbox_ = new OwnedMailbox(helper);
31 base::Bind(&ReflectorImpl::InitOnImplThread, this)); 32 impl_message_loop_->PostTask(FROM_HERE,
33 base::Bind(&ReflectorImpl::InitOnImplThread,
34 this,
35 main_thread_mailbox_->holder()));
32 } 36 }
33 37
34 void ReflectorImpl::InitOnImplThread() { 38 void ReflectorImpl::InitOnImplThread(const gpu::MailboxHolder& mailbox_holder) {
35 // Ignore if the reflector was shutdown before 39 // Ignore if the reflector was shutdown before
36 // initialized, or it's already initialized. 40 // initialized, or it's already initialized.
37 if (!output_surface_map_ || gl_helper_.get()) 41 if (!output_surface_map_ || gl_helper_.get())
38 return; 42 return;
39 43
44 impl_thread_mailbox_holder_ = mailbox_holder;
45
40 BrowserCompositorOutputSurface* source_surface = 46 BrowserCompositorOutputSurface* source_surface =
41 output_surface_map_->Lookup(surface_id_); 47 output_surface_map_->Lookup(surface_id_);
42 // Skip if the source surface isn't ready yet. This will be 48 // Skip if the source surface isn't ready yet. This will be
43 // initiailze when the source surface becomes ready. 49 // initialized when the source surface becomes ready.
44 if (!source_surface) 50 if (!source_surface)
45 return; 51 return;
46 52
47 AttachToOutputSurfaceOnImplThread(source_surface); 53 AttachToOutputSurfaceOnImplThread(impl_thread_mailbox_holder_,
48 // The shared texture doesn't have the data, so invokes full redraw 54 source_surface);
49 // now.
50 main_message_loop_->PostTask(
51 FROM_HERE,
52 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
53 scoped_refptr<ReflectorImpl>(this)));
54 } 55 }
55 56
56 void ReflectorImpl::OnSourceSurfaceReady(int surface_id) { 57 void ReflectorImpl::OnSourceSurfaceReady(
57 DCHECK_EQ(surface_id_, surface_id); 58 BrowserCompositorOutputSurface* source_surface) {
58 InitOnImplThread(); 59 AttachToOutputSurfaceOnImplThread(impl_thread_mailbox_holder_,
60 source_surface);
59 } 61 }
60 62
61 void ReflectorImpl::Shutdown() { 63 void ReflectorImpl::Shutdown() {
62 mirroring_compositor_ = NULL; 64 main_thread_mailbox_ = NULL;
65 mirroring_layer_->SetShowPaintedContent();
63 mirroring_layer_ = NULL; 66 mirroring_layer_ = NULL;
64 {
65 base::AutoLock lock(texture_lock_);
66 texture_id_ = 0;
67 }
68 shared_texture_ = NULL;
69 impl_message_loop_->PostTask( 67 impl_message_loop_->PostTask(
70 FROM_HERE, 68 FROM_HERE,
71 base::Bind(&ReflectorImpl::ShutdownOnImplThread, this)); 69 base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
72 } 70 }
73 71
72 void ReflectorImpl::DetachFromOutputSurface() {
73 DCHECK(output_surface_);
74 output_surface_->SetReflector(NULL);
75 DCHECK(impl_thread_texture_id_);
76 gl_helper_->DeleteTexture(impl_thread_texture_id_);
77 impl_thread_texture_id_ = 0;
78 gl_helper_.reset();
79 output_surface_ = NULL;
80 }
81
74 void ReflectorImpl::ShutdownOnImplThread() { 82 void ReflectorImpl::ShutdownOnImplThread() {
75 BrowserCompositorOutputSurface* output_surface = 83 if (output_surface_)
76 output_surface_map_->Lookup(surface_id_); 84 DetachFromOutputSurface();
77 if (output_surface)
78 output_surface->SetReflector(NULL);
79 output_surface_map_ = NULL; 85 output_surface_map_ = NULL;
80 gl_helper_.reset();
81 // The instance must be deleted on main thread. 86 // The instance must be deleted on main thread.
82 main_message_loop_->PostTask( 87 main_message_loop_->PostTask(
83 FROM_HERE, 88 FROM_HERE,
84 base::Bind(&ReflectorImpl::DeleteOnMainThread, 89 base::Bind(&ReflectorImpl::DeleteOnMainThread,
85 scoped_refptr<ReflectorImpl>(this))); 90 scoped_refptr<ReflectorImpl>(this)));
86 } 91 }
87 92
88 void ReflectorImpl::ReattachToOutputSurfaceFromMainThread( 93 void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
89 BrowserCompositorOutputSurface* output_surface) { 94 BrowserCompositorOutputSurface* output_surface) {
95 GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
96 main_thread_mailbox_ = new OwnedMailbox(helper);
97 needs_set_mailbox_ = true;
90 impl_message_loop_->PostTask( 98 impl_message_loop_->PostTask(
91 FROM_HERE, 99 FROM_HERE,
92 base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread, 100 base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
93 this, output_surface)); 101 this,
102 main_thread_mailbox_->holder(),
103 output_surface));
94 } 104 }
95 105
96 void ReflectorImpl::OnMirroringCompositorResized() { 106 void ReflectorImpl::OnMirroringCompositorResized() {
97 mirroring_compositor_->ScheduleFullRedraw(); 107 mirroring_layer_->SchedulePaint(mirroring_layer_->bounds());
98 } 108 }
99 109
100 void ReflectorImpl::OnLostResources() { 110 void ReflectorImpl::OnSwapBuffers() {
101 mirroring_layer_->SetShowPaintedContent(); 111 gfx::Size size = output_surface_->SurfaceSize();
102 } 112 if (impl_thread_texture_id_) {
103 113 gl_helper_->CopyTextureFullImage(impl_thread_texture_id_, size);
104 void ReflectorImpl::OnReshape(gfx::Size size) { 114 gl_helper_->Flush();
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 }
115 main_message_loop_->PostTask( 116 main_message_loop_->PostTask(
116 FROM_HERE, 117 FROM_HERE,
117 base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread, 118 base::Bind(
118 this->AsWeakPtr(), 119 &ReflectorImpl::FullRedrawOnMainThread, this->AsWeakPtr(), size));
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 } 120 }
136 121
137 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) { 122 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
138 { 123 if (impl_thread_texture_id_) {
139 base::AutoLock lock(texture_lock_); 124 gl_helper_->CopyTextureSubImage(impl_thread_texture_id_, rect);
140 if (texture_id_) { 125 gl_helper_->Flush();
141 gl_helper_->CopyTextureSubImage(texture_id_, rect);
142 gl_helper_->Flush();
143 }
144 } 126 }
145 main_message_loop_->PostTask( 127 main_message_loop_->PostTask(
146 FROM_HERE, 128 FROM_HERE,
147 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread, 129 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
148 this->AsWeakPtr(), 130 this->AsWeakPtr(),
149 texture_size_, 131 output_surface_->SurfaceSize(),
150 rect)); 132 rect));
151 } 133 }
152 134
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() { 135 ReflectorImpl::~ReflectorImpl() {
168 // Make sure the reflector is deleted on main thread. 136 // Make sure the reflector is deleted on main thread.
169 DCHECK_EQ(main_message_loop_.get(), 137 DCHECK_EQ(main_message_loop_.get(),
170 base::MessageLoopProxy::current().get()); 138 base::MessageLoopProxy::current().get());
171 } 139 }
172 140
141 static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox,
142 unsigned int sync_point,
143 bool is_lost) {
144 mailbox->UpdateSyncPoint(sync_point);
145 }
146
173 void ReflectorImpl::AttachToOutputSurfaceOnImplThread( 147 void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
148 const gpu::MailboxHolder& mailbox_holder,
174 BrowserCompositorOutputSurface* output_surface) { 149 BrowserCompositorOutputSurface* output_surface) {
150 if (output_surface == output_surface_)
151 return;
152 if (output_surface_)
153 DetachFromOutputSurface();
154 output_surface_ = output_surface;
175 output_surface->context_provider()->BindToCurrentThread(); 155 output_surface->context_provider()->BindToCurrentThread();
176 gl_helper_.reset( 156 gl_helper_.reset(
177 new GLHelper(output_surface->context_provider()->ContextGL(), 157 new GLHelper(output_surface->context_provider()->ContextGL(),
178 output_surface->context_provider()->ContextSupport())); 158 output_surface->context_provider()->ContextSupport()));
159 impl_thread_texture_id_ = gl_helper_->ConsumeMailboxToTexture(
160 mailbox_holder.mailbox, mailbox_holder.sync_point);
161 gl_helper_->ResizeTexture(impl_thread_texture_id_,
162 output_surface->SurfaceSize());
163 gl_helper_->Flush();
179 output_surface->SetReflector(this); 164 output_surface->SetReflector(this);
165 // The texture doesn't have the data, so invokes full redraw now.
180 main_message_loop_->PostTask( 166 main_message_loop_->PostTask(
181 FROM_HERE, 167 FROM_HERE,
182 base::Bind(&ReflectorImpl::CreateSharedTextureOnMainThread, 168 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
183 this->AsWeakPtr(), 169 scoped_refptr<ReflectorImpl>(this)));
184 texture_size_));
185 } 170 }
186 171
187 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) { 172 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
188 if (!mirroring_layer_) 173 if (!mirroring_layer_ || !main_thread_mailbox_ ||
174 main_thread_mailbox_->mailbox().IsZero())
danakj 2014/04/08 16:08:01 I'm not sure where this method is all called, but
piman 2014/04/08 23:17:46 It can't fail in ReattachToOutputSurfaceFromMainTh
189 return; 175 return;
176 if (needs_set_mailbox_) {
177 mirroring_layer_->SetTextureMailbox(
178 cc::TextureMailbox(main_thread_mailbox_->holder()),
179 cc::SingleReleaseCallback::Create(
180 base::Bind(ReleaseMailbox, main_thread_mailbox_)),
181 size);
182 needs_set_mailbox_ = false;
183 } else if (size != texture_size_) {
danakj 2014/04/08 16:08:01 This texture_size_ is only here to prevent extra c
piman 2014/04/08 23:17:46 I wanted to avoid full layer invalidations if the
184 mirroring_layer_->SetTextureSize(size);
185 } else {
186 return;
187 }
190 mirroring_layer_->SetBounds(gfx::Rect(size)); 188 mirroring_layer_->SetBounds(gfx::Rect(size));
189 texture_size_ = size;
191 } 190 }
192 191
193 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) { 192 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
194 if (!mirroring_compositor_) 193 if (!mirroring_layer_)
195 return; 194 return;
196 UpdateTextureSizeOnMainThread(size); 195 UpdateTextureSizeOnMainThread(size);
197 mirroring_compositor_->ScheduleFullRedraw(); 196 mirroring_layer_->SchedulePaint(mirroring_layer_->bounds());
198 } 197 }
199 198
200 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size, 199 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
201 gfx::Rect rect) { 200 gfx::Rect rect) {
202 if (!mirroring_compositor_) 201 if (!mirroring_layer_)
203 return; 202 return;
204 UpdateTextureSizeOnMainThread(size); 203 UpdateTextureSizeOnMainThread(size);
205 // Flip the coordinates to compositor's one. 204 // Flip the coordinates to compositor's one.
206 int y = size.height() - rect.y() - rect.height(); 205 int y = size.height() - rect.y() - rect.height();
207 gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height()); 206 gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
208 mirroring_layer_->SchedulePaint(new_rect); 207 mirroring_layer_->SchedulePaint(new_rect);
209 } 208 }
210 209
211 void ReflectorImpl::FullRedrawContentOnMainThread() { 210 void ReflectorImpl::FullRedrawContentOnMainThread() {
212 mirrored_compositor_->ScheduleFullRedraw(); 211 mirrored_compositor_->ScheduleFullRedraw();
213 } 212 }
214 213
215 } // namespace content 214 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698