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

Side by Side Diff: content/browser/android/in_process/synchronous_compositor_output_surface.cc

Issue 287993004: [Android WebView] Implement Ubercomp for Render Thread support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: init tear down factored out separately Created 6 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/android/in_process/synchronous_compositor_output_surfa ce.h" 5 #include "content/browser/android/in_process/synchronous_compositor_output_surfa ce.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "cc/output/begin_frame_args.h" 9 #include "cc/output/begin_frame_args.h"
10 #include "cc/output/compositor_frame.h" 10 #include "cc/output/compositor_frame.h"
11 #include "cc/output/context_provider.h" 11 #include "cc/output/context_provider.h"
12 #include "cc/output/output_surface_client.h" 12 #include "cc/output/output_surface_client.h"
13 #include "cc/output/software_output_device.h" 13 #include "cc/output/software_output_device.h"
14 #include "content/browser/android/in_process/synchronous_compositor_impl.h" 14 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
15 #include "content/browser/gpu/compositor_util.h"
15 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
16 #include "gpu/command_buffer/client/gles2_interface.h" 17 #include "gpu/command_buffer/client/gles2_interface.h"
17 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 18 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
18 #include "third_party/skia/include/core/SkCanvas.h" 19 #include "third_party/skia/include/core/SkCanvas.h"
19 #include "ui/gfx/rect_conversions.h" 20 #include "ui/gfx/rect_conversions.h"
20 #include "ui/gfx/skia_util.h" 21 #include "ui/gfx/skia_util.h"
21 #include "ui/gfx/transform.h" 22 #include "ui/gfx/transform.h"
22 23
23 namespace content { 24 namespace content {
24 25
(...skipping 16 matching lines...) Expand all
41 } 42 }
42 virtual void Resize(const gfx::Size& pixel_size, 43 virtual void Resize(const gfx::Size& pixel_size,
43 float scale_factor) OVERRIDE { 44 float scale_factor) OVERRIDE {
44 // Intentional no-op: canvas size is controlled by the embedder. 45 // Intentional no-op: canvas size is controlled by the embedder.
45 } 46 }
46 virtual SkCanvas* BeginPaint(const gfx::Rect& damage_rect) OVERRIDE { 47 virtual SkCanvas* BeginPaint(const gfx::Rect& damage_rect) OVERRIDE {
47 if (!surface_->current_sw_canvas_) { 48 if (!surface_->current_sw_canvas_) {
48 NOTREACHED() << "BeginPaint with no canvas set"; 49 NOTREACHED() << "BeginPaint with no canvas set";
49 return &null_canvas_; 50 return &null_canvas_;
50 } 51 }
51 LOG_IF(WARNING, surface_->did_swap_buffer_) 52 LOG_IF(WARNING, surface_->frame_holder_.get())
52 << "Mutliple calls to BeginPaint per frame"; 53 << "Mutliple calls to BeginPaint per frame";
53 return surface_->current_sw_canvas_; 54 return surface_->current_sw_canvas_;
54 } 55 }
55 virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE { 56 virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE {
56 } 57 }
57 virtual void CopyToPixels(const gfx::Rect& rect, void* pixels) OVERRIDE { 58 virtual void CopyToPixels(const gfx::Rect& rect, void* pixels) OVERRIDE {
58 NOTIMPLEMENTED(); 59 NOTIMPLEMENTED();
59 } 60 }
60 61
61 private: 62 private:
62 SynchronousCompositorOutputSurface* surface_; 63 SynchronousCompositorOutputSurface* surface_;
63 SkCanvas null_canvas_; 64 SkCanvas null_canvas_;
64 65
65 DISALLOW_COPY_AND_ASSIGN(SoftwareDevice); 66 DISALLOW_COPY_AND_ASSIGN(SoftwareDevice);
66 }; 67 };
67 68
68 SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( 69 SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
69 int routing_id) 70 int routing_id)
70 : cc::OutputSurface( 71 : cc::OutputSurface(
71 scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareDevice(this))), 72 scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareDevice(this))),
72 routing_id_(routing_id), 73 routing_id_(routing_id),
73 needs_begin_frame_(false), 74 needs_begin_frame_(false),
74 invoking_composite_(false), 75 invoking_composite_(false),
75 did_swap_buffer_(false),
76 current_sw_canvas_(NULL), 76 current_sw_canvas_(NULL),
77 memory_policy_(0), 77 memory_policy_(0),
78 output_surface_client_(NULL), 78 output_surface_client_(NULL) {
79 weak_ptr_factory_(this) {
80 capabilities_.deferred_gl_initialization = true; 79 capabilities_.deferred_gl_initialization = true;
81 capabilities_.draw_and_swap_full_viewport_every_frame = true; 80 capabilities_.draw_and_swap_full_viewport_every_frame = true;
82 capabilities_.adjust_deadline_for_parent = false; 81 capabilities_.adjust_deadline_for_parent = false;
82 if (IsDelegatedRendererEnabled()) {
83 capabilities_.delegated_rendering = true;
84 capabilities_.max_frames_pending = 1;
85 }
83 // Cannot call out to GetDelegate() here as the output surface is not 86 // Cannot call out to GetDelegate() here as the output surface is not
84 // constructed on the correct thread. 87 // constructed on the correct thread.
85 88
86 memory_policy_.priority_cutoff_when_visible = 89 memory_policy_.priority_cutoff_when_visible =
87 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; 90 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
88 } 91 }
89 92
90 SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() { 93 SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {
91 DCHECK(CalledOnValidThread()); 94 DCHECK(CalledOnValidThread());
92 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate(); 95 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 130
128 void SynchronousCompositorOutputSurface::SetNeedsBeginFrame(bool enable) { 131 void SynchronousCompositorOutputSurface::SetNeedsBeginFrame(bool enable) {
129 DCHECK(CalledOnValidThread()); 132 DCHECK(CalledOnValidThread());
130 needs_begin_frame_ = enable; 133 needs_begin_frame_ = enable;
131 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate(); 134 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
132 if (delegate && !invoking_composite_) 135 if (delegate && !invoking_composite_)
133 delegate->SetContinuousInvalidate(needs_begin_frame_); 136 delegate->SetContinuousInvalidate(needs_begin_frame_);
134 } 137 }
135 138
136 void SynchronousCompositorOutputSurface::SwapBuffers( 139 void SynchronousCompositorOutputSurface::SwapBuffers(
137 cc::CompositorFrame* frame) { 140 cc::CompositorFrame* frame) {
danakj 2014/05/23 19:54:56 We should make this a scoped_ptr in the future may
boliu 2014/05/23 20:36:51 Yeah, I agree that would make more sense.
138 DCHECK(CalledOnValidThread()); 141 DCHECK(CalledOnValidThread());
139 if (!ForcedDrawToSoftwareDevice()) { 142 if (!ForcedDrawToSoftwareDevice() && !IsDelegatedRendererEnabled()) {
140 DCHECK(context_provider_); 143 DCHECK(context_provider_);
141 context_provider_->ContextGL()->ShallowFlushCHROMIUM(); 144 context_provider_->ContextGL()->ShallowFlushCHROMIUM();
142 } 145 }
143 UpdateFrameMetaData(frame->metadata);
144 146
145 did_swap_buffer_ = true; 147 frame_holder_.reset(new cc::CompositorFrame);
148 frame->AssignTo(frame_holder_.get());
149
146 client_->DidSwapBuffers(); 150 client_->DidSwapBuffers();
147 } 151 }
148 152
149 void SynchronousCompositorOutputSurface::UpdateFrameMetaData(
150 const cc::CompositorFrameMetadata& frame_info) {
151 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
152 BrowserThread::PostTask(
153 BrowserThread::UI,
154 FROM_HERE,
155 base::Bind(&SynchronousCompositorOutputSurface::UpdateFrameMetaData,
156 weak_ptr_factory_.GetWeakPtr(),
157 frame_info));
158 return;
159 }
160
161 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
162 if (delegate)
163 delegate->UpdateFrameMetaData(frame_info);
164 }
165
166 namespace { 153 namespace {
167 void AdjustTransform(gfx::Transform* transform, gfx::Rect viewport) { 154 void AdjustTransform(gfx::Transform* transform, gfx::Rect viewport) {
168 // CC's draw origin starts at the viewport. 155 // CC's draw origin starts at the viewport.
169 transform->matrix().postTranslate(-viewport.x(), -viewport.y(), 0); 156 transform->matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
170 } 157 }
171 } // namespace 158 } // namespace
172 159
173 bool SynchronousCompositorOutputSurface::InitializeHwDraw( 160 bool SynchronousCompositorOutputSurface::InitializeHwDraw(
174 scoped_refptr<cc::ContextProvider> onscreen_context_provider) { 161 scoped_refptr<cc::ContextProvider> onscreen_context_provider) {
175 DCHECK(CalledOnValidThread()); 162 DCHECK(CalledOnValidThread());
176 DCHECK(HasClient()); 163 DCHECK(HasClient());
177 DCHECK(!context_provider_); 164 DCHECK(!context_provider_);
178 165
179 return InitializeAndSetContext3d(onscreen_context_provider); 166 return InitializeAndSetContext3d(onscreen_context_provider);
180 } 167 }
181 168
182 void SynchronousCompositorOutputSurface::ReleaseHwDraw() { 169 void SynchronousCompositorOutputSurface::ReleaseHwDraw() {
183 DCHECK(CalledOnValidThread()); 170 DCHECK(CalledOnValidThread());
184 cc::OutputSurface::ReleaseGL(); 171 cc::OutputSurface::ReleaseGL();
185 } 172 }
186 173
187 bool SynchronousCompositorOutputSurface::DemandDrawHw( 174 scoped_ptr<cc::CompositorFrame>
175 SynchronousCompositorOutputSurface::DemandDrawHw(
188 gfx::Size surface_size, 176 gfx::Size surface_size,
189 const gfx::Transform& transform, 177 const gfx::Transform& transform,
190 gfx::Rect viewport, 178 gfx::Rect viewport,
191 gfx::Rect clip, 179 gfx::Rect clip,
192 bool stencil_enabled) { 180 bool stencil_enabled) {
193 DCHECK(CalledOnValidThread()); 181 DCHECK(CalledOnValidThread());
194 DCHECK(HasClient()); 182 DCHECK(HasClient());
195 DCHECK(context_provider_); 183 DCHECK(context_provider_);
196 184
197 surface_size_ = surface_size; 185 surface_size_ = surface_size;
198 SetExternalStencilTest(stencil_enabled); 186 SetExternalStencilTest(stencil_enabled);
199 InvokeComposite(transform, viewport, clip, true); 187 InvokeComposite(transform, viewport, clip, true);
200 188
201 return did_swap_buffer_; 189 return frame_holder_.Pass();
202 } 190 }
203 191
204 bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) { 192 scoped_ptr<cc::CompositorFrame>
193 SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
205 DCHECK(CalledOnValidThread()); 194 DCHECK(CalledOnValidThread());
206 DCHECK(canvas); 195 DCHECK(canvas);
207 DCHECK(!current_sw_canvas_); 196 DCHECK(!current_sw_canvas_);
208 base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas); 197 base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas);
209 198
210 SkIRect canvas_clip; 199 SkIRect canvas_clip;
211 canvas->getClipDeviceBounds(&canvas_clip); 200 canvas->getClipDeviceBounds(&canvas_clip);
212 gfx::Rect clip = gfx::SkIRectToRect(canvas_clip); 201 gfx::Rect clip = gfx::SkIRectToRect(canvas_clip);
213 202
214 gfx::Transform transform(gfx::Transform::kSkipInitialization); 203 gfx::Transform transform(gfx::Transform::kSkipInitialization);
215 transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4. 204 transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4.
216 205
217 surface_size_ = gfx::Size(canvas->getDeviceSize().width(), 206 surface_size_ = gfx::Size(canvas->getDeviceSize().width(),
218 canvas->getDeviceSize().height()); 207 canvas->getDeviceSize().height());
219 SetExternalStencilTest(false); 208 SetExternalStencilTest(false);
220 209
221 InvokeComposite(transform, clip, clip, false); 210 InvokeComposite(transform, clip, clip, false);
222 211
223 return did_swap_buffer_; 212 return frame_holder_.Pass();
224 } 213 }
225 214
226 void SynchronousCompositorOutputSurface::InvokeComposite( 215 void SynchronousCompositorOutputSurface::InvokeComposite(
227 const gfx::Transform& transform, 216 const gfx::Transform& transform,
228 gfx::Rect viewport, 217 gfx::Rect viewport,
229 gfx::Rect clip, 218 gfx::Rect clip,
230 bool valid_for_tile_management) { 219 bool valid_for_tile_management) {
231 DCHECK(!invoking_composite_); 220 DCHECK(!invoking_composite_);
221 DCHECK(!frame_holder_.get());
232 base::AutoReset<bool> invoking_composite_resetter(&invoking_composite_, true); 222 base::AutoReset<bool> invoking_composite_resetter(&invoking_composite_, true);
233 did_swap_buffer_ = false;
234 223
235 gfx::Transform adjusted_transform = transform; 224 gfx::Transform adjusted_transform = transform;
236 AdjustTransform(&adjusted_transform, viewport); 225 AdjustTransform(&adjusted_transform, viewport);
237 SetExternalDrawConstraints( 226 SetExternalDrawConstraints(
238 adjusted_transform, viewport, clip, valid_for_tile_management); 227 adjusted_transform, viewport, clip, valid_for_tile_management);
239 SetNeedsRedrawRect(gfx::Rect(viewport.size())); 228 SetNeedsRedrawRect(gfx::Rect(viewport.size()));
240 client_->BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor()); 229 client_->BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor());
241 230
242 // After software draws (which might move the viewport arbitrarily), restore 231 // After software draws (which might move the viewport arbitrarily), restore
243 // the previous hardware viewport to allow CC's tile manager to prioritize 232 // the previous hardware viewport to allow CC's tile manager to prioritize
244 // properly. 233 // properly.
245 if (valid_for_tile_management) { 234 if (valid_for_tile_management) {
246 cached_hw_transform_ = adjusted_transform; 235 cached_hw_transform_ = adjusted_transform;
247 cached_hw_viewport_ = viewport; 236 cached_hw_viewport_ = viewport;
248 cached_hw_clip_ = clip; 237 cached_hw_clip_ = clip;
249 } else { 238 } else {
250 SetExternalDrawConstraints( 239 SetExternalDrawConstraints(
251 cached_hw_transform_, cached_hw_viewport_, cached_hw_clip_, true); 240 cached_hw_transform_, cached_hw_viewport_, cached_hw_clip_, true);
252 } 241 }
253 242
254 if (did_swap_buffer_) 243 if (frame_holder_.get())
255 client_->DidSwapBuffersComplete(); 244 client_->DidSwapBuffersComplete();
256 245
257 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate(); 246 SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
258 if (delegate) 247 if (delegate)
259 delegate->SetContinuousInvalidate(needs_begin_frame_); 248 delegate->SetContinuousInvalidate(needs_begin_frame_);
260 } 249 }
261 250
251 void SynchronousCompositorOutputSurface::ReturnResources(
252 const cc::CompositorFrameAck& frame_ack) {
253 ReclaimResources(&frame_ack);
254 }
255
262 void SynchronousCompositorOutputSurface::SetMemoryPolicy( 256 void SynchronousCompositorOutputSurface::SetMemoryPolicy(
263 const SynchronousCompositorMemoryPolicy& policy) { 257 const SynchronousCompositorMemoryPolicy& policy) {
264 DCHECK(CalledOnValidThread()); 258 DCHECK(CalledOnValidThread());
265 memory_policy_.bytes_limit_when_visible = policy.bytes_limit; 259 memory_policy_.bytes_limit_when_visible = policy.bytes_limit;
266 memory_policy_.num_resources_limit = policy.num_resources_limit; 260 memory_policy_.num_resources_limit = policy.num_resources_limit;
267 261
268 if (output_surface_client_) 262 if (output_surface_client_)
269 output_surface_client_->SetMemoryPolicy(memory_policy_); 263 output_surface_client_->SetMemoryPolicy(memory_policy_);
270 } 264 }
271 265
272 // Not using base::NonThreadSafe as we want to enforce a more exacting threading 266 // Not using base::NonThreadSafe as we want to enforce a more exacting threading
273 // requirement: SynchronousCompositorOutputSurface() must only be used on the UI 267 // requirement: SynchronousCompositorOutputSurface() must only be used on the UI
274 // thread. 268 // thread.
275 bool SynchronousCompositorOutputSurface::CalledOnValidThread() const { 269 bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
276 return BrowserThread::CurrentlyOn(BrowserThread::UI); 270 return BrowserThread::CurrentlyOn(BrowserThread::UI);
277 } 271 }
278 272
279 SynchronousCompositorOutputSurfaceDelegate* 273 SynchronousCompositorOutputSurfaceDelegate*
280 SynchronousCompositorOutputSurface::GetDelegate() { 274 SynchronousCompositorOutputSurface::GetDelegate() {
281 return SynchronousCompositorImpl::FromRoutingID(routing_id_); 275 return SynchronousCompositorImpl::FromRoutingID(routing_id_);
282 } 276 }
283 277
284 } // namespace content 278 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698