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

Side by Side Diff: content/renderer/android/synchronous_compositor_output_surface.cc

Issue 2128113002: Use a cc::Display for WebView resourceless software draws. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: displaywebview: dcheck Created 4 years, 5 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
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/renderer/android/synchronous_compositor_output_surface.h" 5 #include "content/renderer/android/synchronous_compositor_output_surface.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
15 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
16 #include "cc/output/compositor_frame.h" 16 #include "cc/output/compositor_frame.h"
17 #include "cc/output/context_provider.h" 17 #include "cc/output/context_provider.h"
18 #include "cc/output/output_surface_client.h" 18 #include "cc/output/output_surface_client.h"
19 #include "cc/output/renderer_settings.h"
19 #include "cc/output/software_output_device.h" 20 #include "cc/output/software_output_device.h"
21 #include "cc/output/texture_mailbox_deleter.h"
boliu 2016/07/07 00:37:54 is this needed?
danakj 2016/07/07 00:46:30 Ya, it's written as nullptr, but it fails to compi
22 #include "cc/surfaces/surface_factory.h"
23 #include "cc/surfaces/surface_id_allocator.h"
24 #include "cc/surfaces/surface_manager.h"
20 #include "content/common/android/sync_compositor_messages.h" 25 #include "content/common/android/sync_compositor_messages.h"
21 #include "content/renderer/android/synchronous_compositor_filter.h" 26 #include "content/renderer/android/synchronous_compositor_filter.h"
22 #include "content/renderer/android/synchronous_compositor_registry.h" 27 #include "content/renderer/android/synchronous_compositor_registry.h"
23 #include "content/renderer/gpu/frame_swap_message_queue.h" 28 #include "content/renderer/gpu/frame_swap_message_queue.h"
24 #include "content/renderer/render_thread_impl.h" 29 #include "content/renderer/render_thread_impl.h"
25 #include "gpu/command_buffer/client/context_support.h" 30 #include "gpu/command_buffer/client/context_support.h"
26 #include "gpu/command_buffer/client/gles2_interface.h" 31 #include "gpu/command_buffer/client/gles2_interface.h"
27 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 32 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
28 #include "ipc/ipc_message.h" 33 #include "ipc/ipc_message.h"
29 #include "ipc/ipc_message_macros.h" 34 #include "ipc/ipc_message_macros.h"
30 #include "ipc/ipc_sender.h" 35 #include "ipc/ipc_sender.h"
31 #include "third_party/skia/include/core/SkCanvas.h" 36 #include "third_party/skia/include/core/SkCanvas.h"
32 #include "ui/gfx/geometry/rect_conversions.h" 37 #include "ui/gfx/geometry/rect_conversions.h"
33 #include "ui/gfx/skia_util.h" 38 #include "ui/gfx/skia_util.h"
34 #include "ui/gfx/transform.h" 39 #include "ui/gfx/transform.h"
35 40
36 namespace content { 41 namespace content {
37 42
38 namespace { 43 namespace {
39 44
40 const int64_t kFallbackTickTimeoutInMilliseconds = 100; 45 const int64_t kFallbackTickTimeoutInMilliseconds = 100;
46 const uint32_t kCompositorSurfaceNamespace = 1;
41 47
42 // Do not limit number of resources, so use an unrealistically high value. 48 // Do not limit number of resources, so use an unrealistically high value.
43 const size_t kNumResourcesLimit = 10 * 1000 * 1000; 49 const size_t kNumResourcesLimit = 10 * 1000 * 1000;
44 50
45 } // namespace 51 } // namespace
46 52
47 class SynchronousCompositorOutputSurface::SoftwareDevice 53 class SoftwareDevice : public cc::SoftwareOutputDevice {
48 : public cc::SoftwareOutputDevice {
49 public: 54 public:
50 SoftwareDevice(SynchronousCompositorOutputSurface* surface) 55 SoftwareDevice(SkCanvas** canvas) : canvas_(canvas) {}
51 : surface_(surface) { 56
52 }
53 void Resize(const gfx::Size& pixel_size, float scale_factor) override { 57 void Resize(const gfx::Size& pixel_size, float scale_factor) override {
54 // Intentional no-op: canvas size is controlled by the embedder. 58 // Intentional no-op: canvas size is controlled by the embedder.
55 } 59 }
56 SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override { 60 SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
57 if (!surface_->current_sw_canvas_) { 61 DCHECK(*canvas_) << "BeginPaint with no canvas set";
58 NOTREACHED() << "BeginPaint with no canvas set"; 62 return *canvas_;
59 return &null_canvas_;
60 }
61 LOG_IF(WARNING, surface_->did_swap_)
62 << "Mutliple calls to BeginPaint per frame";
63 return surface_->current_sw_canvas_;
64 } 63 }
65 void EndPaint() override {} 64 void EndPaint() override {}
66 65
67 private: 66 private:
68 SynchronousCompositorOutputSurface* surface_; 67 SkCanvas** canvas_;
69 SkCanvas null_canvas_;
70 68
71 DISALLOW_COPY_AND_ASSIGN(SoftwareDevice); 69 DISALLOW_COPY_AND_ASSIGN(SoftwareDevice);
72 }; 70 };
73 71
72 class SoftwareOutputSurface : public cc::OutputSurface {
73 public:
74 SoftwareOutputSurface(std::unique_ptr<SoftwareDevice> software_device)
75 : cc::OutputSurface(nullptr, nullptr, std::move(software_device)) {}
76
77 // cc::OutputSurface implementation.
78 uint32_t GetFramebufferCopyTextureFormat() override { return 0; }
79 void SwapBuffers(cc::CompositorFrame frame) override {}
80 };
81
74 SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( 82 SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
75 scoped_refptr<cc::ContextProvider> context_provider, 83 scoped_refptr<cc::ContextProvider> context_provider,
76 scoped_refptr<cc::ContextProvider> worker_context_provider, 84 scoped_refptr<cc::ContextProvider> worker_context_provider,
85 cc::SharedBitmapManager* shared_bitmap_manager,
77 int routing_id, 86 int routing_id,
78 uint32_t output_surface_id, 87 uint32_t output_surface_id,
79 SynchronousCompositorRegistry* registry, 88 SynchronousCompositorRegistry* registry,
80 scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue) 89 scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue)
81 : cc::OutputSurface(std::move(context_provider), 90 : cc::OutputSurface(std::move(context_provider),
82 std::move(worker_context_provider), 91 std::move(worker_context_provider),
83 base::MakeUnique<SoftwareDevice>(this)), 92 nullptr),
93 shared_bitmap_manager_(shared_bitmap_manager),
84 routing_id_(routing_id), 94 routing_id_(routing_id),
85 output_surface_id_(output_surface_id), 95 output_surface_id_(output_surface_id),
86 registry_(registry), 96 registry_(registry),
87 sender_(RenderThreadImpl::current()->sync_compositor_message_filter()), 97 sender_(RenderThreadImpl::current()->sync_compositor_message_filter()),
88 registered_(false),
89 sync_client_(nullptr),
90 current_sw_canvas_(nullptr),
91 memory_policy_(0u), 98 memory_policy_(0u),
92 did_swap_(false),
93 frame_swap_message_queue_(frame_swap_message_queue), 99 frame_swap_message_queue_(frame_swap_message_queue),
94 fallback_tick_pending_(false), 100 surface_manager_(new cc::SurfaceManager),
95 fallback_tick_running_(false) { 101 surface_id_allocator_(
102 new cc::SurfaceIdAllocator(kCompositorSurfaceNamespace)),
103 surface_factory_(new cc::SurfaceFactory(surface_manager_.get(), this)) {
96 DCHECK(registry_); 104 DCHECK(registry_);
97 DCHECK(sender_); 105 DCHECK(sender_);
98 thread_checker_.DetachFromThread(); 106 thread_checker_.DetachFromThread();
99 capabilities_.adjust_deadline_for_parent = false; 107 capabilities_.adjust_deadline_for_parent = false;
100 capabilities_.delegated_rendering = true; 108 capabilities_.delegated_rendering = true;
101 memory_policy_.priority_cutoff_when_visible = 109 memory_policy_.priority_cutoff_when_visible =
102 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; 110 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
111 surface_id_allocator_->RegisterSurfaceIdNamespace(surface_manager_.get());
103 } 112 }
104 113
105 SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {} 114 SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {}
106 115
107 void SynchronousCompositorOutputSurface::SetSyncClient( 116 void SynchronousCompositorOutputSurface::SetSyncClient(
108 SynchronousCompositorOutputSurfaceClient* compositor) { 117 SynchronousCompositorOutputSurfaceClient* compositor) {
109 DCHECK(CalledOnValidThread()); 118 DCHECK(CalledOnValidThread());
110 sync_client_ = compositor; 119 sync_client_ = compositor;
111 if (sync_client_) 120 if (sync_client_)
112 Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_)); 121 Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_));
(...skipping 15 matching lines...) Expand all
128 DCHECK(CalledOnValidThread()); 137 DCHECK(CalledOnValidThread());
129 if (!cc::OutputSurface::BindToClient(surface_client)) 138 if (!cc::OutputSurface::BindToClient(surface_client))
130 return false; 139 return false;
131 140
132 client_->SetMemoryPolicy(memory_policy_); 141 client_->SetMemoryPolicy(memory_policy_);
133 client_->SetTreeActivationCallback( 142 client_->SetTreeActivationCallback(
134 base::Bind(&SynchronousCompositorOutputSurface::DidActivatePendingTree, 143 base::Bind(&SynchronousCompositorOutputSurface::DidActivatePendingTree,
135 base::Unretained(this))); 144 base::Unretained(this)));
136 registry_->RegisterOutputSurface(routing_id_, this); 145 registry_->RegisterOutputSurface(routing_id_, this);
137 registered_ = true; 146 registered_ = true;
147
148 surface_manager_->RegisterSurfaceFactoryClient(
149 surface_id_allocator_->id_namespace(), this);
150
151 cc::RendererSettings software_renderer_settings;
152
153 display_.reset(new cc::Display(
154 surface_manager_.get(), shared_bitmap_manager_,
155 nullptr /* gpu_memory_buffer_manager */, software_renderer_settings,
156 surface_id_allocator_->id_namespace(), nullptr /* begin_frame_source */,
157 base::MakeUnique<SoftwareOutputSurface>(
158 base::MakeUnique<SoftwareDevice>(&current_sw_canvas_)),
boliu 2016/07/07 00:37:54 just confirming c++11 knowledge :p MakeUnique is d
danakj 2016/07/07 00:46:30 It is a function call, so it returns an rvalue, if
159 nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */));
160 display_->Initialize(&display_client_);
boliu 2016/07/07 00:37:54 GLRenderer used to be created on the stack if thi
danakj 2016/07/07 00:46:30 SoftwareRenderer::DrawPictureQuad doesn't store an
boliu 2016/07/07 00:58:01 Yes please.
danakj 2016/07/07 20:34:07 OK I think that worked. Trying it @ bots now. PTAL
138 return true; 161 return true;
139 } 162 }
140 163
141 void SynchronousCompositorOutputSurface::DetachFromClient() { 164 void SynchronousCompositorOutputSurface::DetachFromClient() {
142 DCHECK(CalledOnValidThread()); 165 DCHECK(CalledOnValidThread());
143 if (registered_) { 166 if (registered_) {
144 registry_->UnregisterOutputSurface(routing_id_, this); 167 registry_->UnregisterOutputSurface(routing_id_, this);
145 } 168 }
146 client_->SetTreeActivationCallback(base::Closure()); 169 client_->SetTreeActivationCallback(base::Closure());
170 if (!delegated_surface_id_.is_null())
171 surface_factory_->Destroy(delegated_surface_id_);
172 surface_manager_->UnregisterSurfaceFactoryClient(
173 surface_id_allocator_->id_namespace());
174 display_ = nullptr;
175 surface_factory_ = nullptr;
176 surface_id_allocator_ = nullptr;
177 surface_manager_ = nullptr;
147 cc::OutputSurface::DetachFromClient(); 178 cc::OutputSurface::DetachFromClient();
148 CancelFallbackTick(); 179 CancelFallbackTick();
149 } 180 }
150 181
151 void SynchronousCompositorOutputSurface::Reshape( 182 void SynchronousCompositorOutputSurface::Reshape(
152 const gfx::Size& size, 183 const gfx::Size& size,
153 float scale_factor, 184 float scale_factor,
154 const gfx::ColorSpace& color_space, 185 const gfx::ColorSpace& color_space,
155 bool has_alpha) { 186 bool has_alpha) {
156 // Intentional no-op: surface size is controlled by the embedder. 187 // Intentional no-op: surface size is controlled by the embedder.
157 } 188 }
158 189
190 static void NoOpDrawCallback(cc::SurfaceDrawStatus s) {}
191
159 void SynchronousCompositorOutputSurface::SwapBuffers( 192 void SynchronousCompositorOutputSurface::SwapBuffers(
160 cc::CompositorFrame frame) { 193 cc::CompositorFrame frame) {
161 DCHECK(CalledOnValidThread()); 194 DCHECK(CalledOnValidThread());
162 DCHECK(sync_client_); 195 DCHECK(sync_client_);
196
197 cc::CompositorFrame swap_frame;
198
199 if (in_software_draw_) {
boliu 2016/07/07 00:37:54 should be ok just skip this and return the resourc
danakj 2016/07/07 00:46:30 Don't produce a frame in fallback tick? So before
boliu 2016/07/07 00:58:01 This is the same behavior. I'm just pointing out a
danakj 2016/07/07 20:34:07 OK ya let me send you a patch and we can see if I
200 // The frame we send to the client is actually just the metadata. Preserve
201 // the |frame| for the software path below.
202 swap_frame.metadata = frame.metadata.Clone();
203
204 if (delegated_surface_id_.is_null()) {
205 delegated_surface_id_ = surface_id_allocator_->GenerateId();
206 surface_factory_->Create(delegated_surface_id_);
207 }
208
209 display_->SetSurfaceId(delegated_surface_id_,
210 frame.metadata.device_scale_factor);
211
212 gfx::Size frame_size =
213 frame.delegated_frame_data->render_pass_list.back()->output_rect.size();
214 display_->Resize(frame_size);
215
216 surface_factory_->SubmitCompositorFrame(
217 delegated_surface_id_, std::move(frame), base::Bind(&NoOpDrawCallback));
218 display_->DrawAndSwap();
219 } else {
220 swap_frame = std::move(frame);
221 }
222
163 if (!fallback_tick_running_) { 223 if (!fallback_tick_running_) {
164 sync_client_->SwapBuffers(output_surface_id_, std::move(frame)); 224 sync_client_->SwapBuffers(output_surface_id_, std::move(swap_frame));
165 DeliverMessages(); 225 DeliverMessages();
166 } 226 }
167 client_->DidSwapBuffers(); 227 client_->DidSwapBuffers();
168 did_swap_ = true; 228 did_swap_ = true;
169 } 229 }
170 230
171 void SynchronousCompositorOutputSurface::CancelFallbackTick() { 231 void SynchronousCompositorOutputSurface::CancelFallbackTick() {
172 fallback_tick_.Cancel(); 232 fallback_tick_.Cancel();
173 fallback_tick_pending_ = false; 233 fallback_tick_pending_ = false;
174 } 234 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 const gfx::Rect& viewport_rect_for_tile_priority, 281 const gfx::Rect& viewport_rect_for_tile_priority,
222 const gfx::Transform& transform_for_tile_priority) { 282 const gfx::Transform& transform_for_tile_priority) {
223 DCHECK(CalledOnValidThread()); 283 DCHECK(CalledOnValidThread());
224 DCHECK(HasClient()); 284 DCHECK(HasClient());
225 DCHECK(context_provider_.get()); 285 DCHECK(context_provider_.get());
226 CancelFallbackTick(); 286 CancelFallbackTick();
227 287
228 surface_size_ = surface_size; 288 surface_size_ = surface_size;
229 client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority, 289 client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority,
230 transform_for_tile_priority); 290 transform_for_tile_priority);
231 const bool software_draw = false; 291 InvokeComposite(transform, viewport, clip);
232 InvokeComposite(transform, viewport, clip, software_draw);
233 } 292 }
234 293
235 void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) { 294 void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
236 DCHECK(CalledOnValidThread()); 295 DCHECK(CalledOnValidThread());
237 DCHECK(canvas); 296 DCHECK(canvas);
238 DCHECK(!current_sw_canvas_); 297 DCHECK(!current_sw_canvas_);
239 CancelFallbackTick(); 298 CancelFallbackTick();
240 299
241 base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas); 300 base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas);
242 301
243 SkIRect canvas_clip; 302 SkIRect canvas_clip;
244 canvas->getClipDeviceBounds(&canvas_clip); 303 canvas->getClipDeviceBounds(&canvas_clip);
245 gfx::Rect clip = gfx::SkIRectToRect(canvas_clip); 304 gfx::Rect clip = gfx::SkIRectToRect(canvas_clip);
246 305
247 gfx::Transform transform(gfx::Transform::kSkipInitialization); 306 gfx::Transform transform(gfx::Transform::kSkipInitialization);
248 transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4. 307 transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4.
249 308
250 surface_size_ = gfx::Size(canvas->getBaseLayerSize().width(), 309 surface_size_ = gfx::Size(canvas->getBaseLayerSize().width(),
251 canvas->getBaseLayerSize().height()); 310 canvas->getBaseLayerSize().height());
252 const bool software_draw = true; 311 base::AutoReset<bool> set_in_software_draw(&in_software_draw_, true);
253 InvokeComposite(transform, clip, clip, software_draw); 312 InvokeComposite(transform, clip, clip);
254 } 313 }
255 314
256 void SynchronousCompositorOutputSurface::InvokeComposite( 315 void SynchronousCompositorOutputSurface::InvokeComposite(
257 const gfx::Transform& transform, 316 const gfx::Transform& transform,
258 const gfx::Rect& viewport, 317 const gfx::Rect& viewport,
259 const gfx::Rect& clip, 318 const gfx::Rect& clip) {
260 bool software_draw) {
261 gfx::Transform adjusted_transform = transform; 319 gfx::Transform adjusted_transform = transform;
262 adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0); 320 adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
263 did_swap_ = false; 321 did_swap_ = false;
264 client_->OnDraw(adjusted_transform, viewport, clip, software_draw); 322 client_->OnDraw(adjusted_transform, viewport, clip, in_software_draw_);
265 323
266 if (did_swap_) 324 if (did_swap_)
267 client_->DidSwapBuffersComplete(); 325 client_->DidSwapBuffersComplete();
268 } 326 }
269 327
270 void SynchronousCompositorOutputSurface::OnReclaimResources( 328 void SynchronousCompositorOutputSurface::OnReclaimResources(
271 uint32_t output_surface_id, 329 uint32_t output_surface_id,
272 const cc::CompositorFrameAck& ack) { 330 const cc::CompositorFrameAck& ack) {
273 // Ignore message if it's a stale one coming from a different output surface 331 // Ignore message if it's a stale one coming from a different output surface
274 // (e.g. after a lost context). 332 // (e.g. after a lost context).
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 376
319 bool SynchronousCompositorOutputSurface::Send(IPC::Message* message) { 377 bool SynchronousCompositorOutputSurface::Send(IPC::Message* message) {
320 DCHECK(CalledOnValidThread()); 378 DCHECK(CalledOnValidThread());
321 return sender_->Send(message); 379 return sender_->Send(message);
322 } 380 }
323 381
324 bool SynchronousCompositorOutputSurface::CalledOnValidThread() const { 382 bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
325 return thread_checker_.CalledOnValidThread(); 383 return thread_checker_.CalledOnValidThread();
326 } 384 }
327 385
386 void SynchronousCompositorOutputSurface::ReturnResources(
387 const cc::ReturnedResourceArray& resources) {
388 cc::CompositorFrameAck ack;
389 ack.resources = resources;
390 client_->ReclaimResources(&ack);
391 }
392
393 void SynchronousCompositorOutputSurface::SetBeginFrameSource(
394 cc::BeginFrameSource* begin_frame_source) {
395 // Software output is synchronous and doesn't use a BeginFrameSource.
396 NOTREACHED();
397 }
398
328 } // namespace content 399 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698