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

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: mojom 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
« no previous file with comments | « content/renderer/android/synchronous_compositor_output_surface.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
22 #include "cc/surfaces/display.h"
23 #include "cc/surfaces/surface_factory.h"
24 #include "cc/surfaces/surface_id_allocator.h"
25 #include "cc/surfaces/surface_manager.h"
20 #include "content/common/android/sync_compositor_messages.h" 26 #include "content/common/android/sync_compositor_messages.h"
21 #include "content/renderer/android/synchronous_compositor_filter.h" 27 #include "content/renderer/android/synchronous_compositor_filter.h"
22 #include "content/renderer/android/synchronous_compositor_registry.h" 28 #include "content/renderer/android/synchronous_compositor_registry.h"
23 #include "content/renderer/gpu/frame_swap_message_queue.h" 29 #include "content/renderer/gpu/frame_swap_message_queue.h"
24 #include "content/renderer/render_thread_impl.h" 30 #include "content/renderer/render_thread_impl.h"
25 #include "gpu/command_buffer/client/context_support.h" 31 #include "gpu/command_buffer/client/context_support.h"
26 #include "gpu/command_buffer/client/gles2_interface.h" 32 #include "gpu/command_buffer/client/gles2_interface.h"
27 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 33 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
28 #include "ipc/ipc_message.h" 34 #include "ipc/ipc_message.h"
29 #include "ipc/ipc_message_macros.h" 35 #include "ipc/ipc_message_macros.h"
30 #include "ipc/ipc_sender.h" 36 #include "ipc/ipc_sender.h"
31 #include "third_party/skia/include/core/SkCanvas.h" 37 #include "third_party/skia/include/core/SkCanvas.h"
32 #include "ui/gfx/geometry/rect_conversions.h" 38 #include "ui/gfx/geometry/rect_conversions.h"
33 #include "ui/gfx/skia_util.h" 39 #include "ui/gfx/skia_util.h"
34 #include "ui/gfx/transform.h" 40 #include "ui/gfx/transform.h"
35 41
36 namespace content { 42 namespace content {
37 43
38 namespace { 44 namespace {
39 45
40 const int64_t kFallbackTickTimeoutInMilliseconds = 100; 46 const int64_t kFallbackTickTimeoutInMilliseconds = 100;
47 const uint32_t kCompositorSurfaceNamespace = 1;
41 48
42 // Do not limit number of resources, so use an unrealistically high value. 49 // Do not limit number of resources, so use an unrealistically high value.
43 const size_t kNumResourcesLimit = 10 * 1000 * 1000; 50 const size_t kNumResourcesLimit = 10 * 1000 * 1000;
44 51
45 } // namespace 52 } // namespace
46 53
47 class SynchronousCompositorOutputSurface::SoftwareDevice 54 class SoftwareDevice : public cc::SoftwareOutputDevice {
48 : public cc::SoftwareOutputDevice {
49 public: 55 public:
50 SoftwareDevice(SynchronousCompositorOutputSurface* surface) 56 SoftwareDevice(SkCanvas** canvas) : canvas_(canvas) {}
51 : surface_(surface) { 57
52 }
53 void Resize(const gfx::Size& pixel_size, float scale_factor) override { 58 void Resize(const gfx::Size& pixel_size, float scale_factor) override {
54 // Intentional no-op: canvas size is controlled by the embedder. 59 // Intentional no-op: canvas size is controlled by the embedder.
55 } 60 }
56 SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override { 61 SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
57 if (!surface_->current_sw_canvas_) { 62 DCHECK(*canvas_) << "BeginPaint with no canvas set";
58 NOTREACHED() << "BeginPaint with no canvas set"; 63 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 } 64 }
65 void EndPaint() override {} 65 void EndPaint() override {}
66 66
67 private: 67 private:
68 SynchronousCompositorOutputSurface* surface_; 68 SkCanvas** canvas_;
69 SkCanvas null_canvas_;
70 69
71 DISALLOW_COPY_AND_ASSIGN(SoftwareDevice); 70 DISALLOW_COPY_AND_ASSIGN(SoftwareDevice);
72 }; 71 };
73 72
73 class SoftwareOutputSurface : public cc::OutputSurface {
74 public:
75 SoftwareOutputSurface(std::unique_ptr<SoftwareDevice> software_device)
76 : cc::OutputSurface(nullptr, nullptr, std::move(software_device)) {}
77
78 // cc::OutputSurface implementation.
79 uint32_t GetFramebufferCopyTextureFormat() override { return 0; }
80 void SwapBuffers(cc::CompositorFrame frame) override {}
81 };
82
74 SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( 83 SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
75 scoped_refptr<cc::ContextProvider> context_provider, 84 scoped_refptr<cc::ContextProvider> context_provider,
76 scoped_refptr<cc::ContextProvider> worker_context_provider, 85 scoped_refptr<cc::ContextProvider> worker_context_provider,
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),
84 routing_id_(routing_id), 93 routing_id_(routing_id),
85 output_surface_id_(output_surface_id), 94 output_surface_id_(output_surface_id),
86 registry_(registry), 95 registry_(registry),
87 sender_(RenderThreadImpl::current()->sync_compositor_message_filter()), 96 sender_(RenderThreadImpl::current()->sync_compositor_message_filter()),
88 registered_(false),
89 sync_client_(nullptr),
90 current_sw_canvas_(nullptr),
91 memory_policy_(0u), 97 memory_policy_(0u),
92 did_swap_(false),
93 frame_swap_message_queue_(frame_swap_message_queue), 98 frame_swap_message_queue_(frame_swap_message_queue),
94 fallback_tick_pending_(false), 99 surface_manager_(new cc::SurfaceManager),
95 fallback_tick_running_(false) { 100 surface_id_allocator_(
101 new cc::SurfaceIdAllocator(kCompositorSurfaceNamespace)),
102 surface_factory_(new cc::SurfaceFactory(surface_manager_.get(), this)) {
96 DCHECK(registry_); 103 DCHECK(registry_);
97 DCHECK(sender_); 104 DCHECK(sender_);
98 thread_checker_.DetachFromThread(); 105 thread_checker_.DetachFromThread();
99 capabilities_.adjust_deadline_for_parent = false; 106 capabilities_.adjust_deadline_for_parent = false;
100 capabilities_.delegated_rendering = true; 107 capabilities_.delegated_rendering = true;
101 memory_policy_.priority_cutoff_when_visible = 108 memory_policy_.priority_cutoff_when_visible =
102 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; 109 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
110 surface_id_allocator_->RegisterSurfaceIdNamespace(surface_manager_.get());
103 } 111 }
104 112
105 SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {} 113 SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {}
106 114
107 void SynchronousCompositorOutputSurface::SetSyncClient( 115 void SynchronousCompositorOutputSurface::SetSyncClient(
108 SynchronousCompositorOutputSurfaceClient* compositor) { 116 SynchronousCompositorOutputSurfaceClient* compositor) {
109 DCHECK(CalledOnValidThread()); 117 DCHECK(CalledOnValidThread());
110 sync_client_ = compositor; 118 sync_client_ = compositor;
111 if (sync_client_) 119 if (sync_client_)
112 Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_)); 120 Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_));
(...skipping 15 matching lines...) Expand all
128 DCHECK(CalledOnValidThread()); 136 DCHECK(CalledOnValidThread());
129 if (!cc::OutputSurface::BindToClient(surface_client)) 137 if (!cc::OutputSurface::BindToClient(surface_client))
130 return false; 138 return false;
131 139
132 client_->SetMemoryPolicy(memory_policy_); 140 client_->SetMemoryPolicy(memory_policy_);
133 client_->SetTreeActivationCallback( 141 client_->SetTreeActivationCallback(
134 base::Bind(&SynchronousCompositorOutputSurface::DidActivatePendingTree, 142 base::Bind(&SynchronousCompositorOutputSurface::DidActivatePendingTree,
135 base::Unretained(this))); 143 base::Unretained(this)));
136 registry_->RegisterOutputSurface(routing_id_, this); 144 registry_->RegisterOutputSurface(routing_id_, this);
137 registered_ = true; 145 registered_ = true;
146
147 surface_manager_->RegisterSurfaceFactoryClient(
148 surface_id_allocator_->id_namespace(), this);
149
150 cc::RendererSettings software_renderer_settings;
151
152 // The shared_bitmap_manager and gpu_memory_buffer_manager here are null as
153 // this Display is only used for resourcesless software draws, where no
154 // resources are included in the frame swapped from the compositor. So there
155 // is no need for these.
156 display_.reset(new cc::Display(
157 surface_manager_.get(), nullptr /* shared_bitmap_manager */,
158 nullptr /* gpu_memory_buffer_manager */, software_renderer_settings,
159 surface_id_allocator_->id_namespace(), nullptr /* begin_frame_source */,
160 base::MakeUnique<SoftwareOutputSurface>(
161 base::MakeUnique<SoftwareDevice>(&current_sw_canvas_)),
162 nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */));
163 display_->Initialize(&display_client_);
138 return true; 164 return true;
139 } 165 }
140 166
141 void SynchronousCompositorOutputSurface::DetachFromClient() { 167 void SynchronousCompositorOutputSurface::DetachFromClient() {
142 DCHECK(CalledOnValidThread()); 168 DCHECK(CalledOnValidThread());
143 if (registered_) { 169 if (registered_) {
144 registry_->UnregisterOutputSurface(routing_id_, this); 170 registry_->UnregisterOutputSurface(routing_id_, this);
145 } 171 }
146 client_->SetTreeActivationCallback(base::Closure()); 172 client_->SetTreeActivationCallback(base::Closure());
173 if (!delegated_surface_id_.is_null())
174 surface_factory_->Destroy(delegated_surface_id_);
175 surface_manager_->UnregisterSurfaceFactoryClient(
176 surface_id_allocator_->id_namespace());
177 display_ = nullptr;
178 surface_factory_ = nullptr;
179 surface_id_allocator_ = nullptr;
180 surface_manager_ = nullptr;
147 cc::OutputSurface::DetachFromClient(); 181 cc::OutputSurface::DetachFromClient();
148 CancelFallbackTick(); 182 CancelFallbackTick();
149 } 183 }
150 184
151 void SynchronousCompositorOutputSurface::Reshape( 185 void SynchronousCompositorOutputSurface::Reshape(
152 const gfx::Size& size, 186 const gfx::Size& size,
153 float scale_factor, 187 float scale_factor,
154 const gfx::ColorSpace& color_space, 188 const gfx::ColorSpace& color_space,
155 bool has_alpha) { 189 bool has_alpha) {
156 // Intentional no-op: surface size is controlled by the embedder. 190 // Intentional no-op: surface size is controlled by the embedder.
157 } 191 }
158 192
193 static void NoOpDrawCallback(cc::SurfaceDrawStatus s) {}
194
159 void SynchronousCompositorOutputSurface::SwapBuffers( 195 void SynchronousCompositorOutputSurface::SwapBuffers(
160 cc::CompositorFrame frame) { 196 cc::CompositorFrame frame) {
161 DCHECK(CalledOnValidThread()); 197 DCHECK(CalledOnValidThread());
162 DCHECK(sync_client_); 198 DCHECK(sync_client_);
199
200 cc::CompositorFrame swap_frame;
201
202 if (in_software_draw_) {
203 // The frame we send to the client is actually just the metadata. Preserve
204 // the |frame| for the software path below.
205 swap_frame.metadata = frame.metadata.Clone();
206
207 if (delegated_surface_id_.is_null()) {
208 delegated_surface_id_ = surface_id_allocator_->GenerateId();
209 surface_factory_->Create(delegated_surface_id_);
210 }
211
212 display_->SetSurfaceId(delegated_surface_id_,
213 frame.metadata.device_scale_factor);
214
215 gfx::Size frame_size =
216 frame.delegated_frame_data->render_pass_list.back()->output_rect.size();
217 display_->Resize(frame_size);
218
219 surface_factory_->SubmitCompositorFrame(
220 delegated_surface_id_, std::move(frame), base::Bind(&NoOpDrawCallback));
221 display_->DrawAndSwap();
222 } else {
223 swap_frame = std::move(frame);
224 }
225
163 if (!fallback_tick_running_) { 226 if (!fallback_tick_running_) {
164 sync_client_->SwapBuffers(output_surface_id_, std::move(frame)); 227 sync_client_->SwapBuffers(output_surface_id_, std::move(swap_frame));
165 DeliverMessages(); 228 DeliverMessages();
166 } 229 }
167 client_->DidSwapBuffers(); 230 client_->DidSwapBuffers();
168 did_swap_ = true; 231 did_swap_ = true;
169 } 232 }
170 233
171 void SynchronousCompositorOutputSurface::CancelFallbackTick() { 234 void SynchronousCompositorOutputSurface::CancelFallbackTick() {
172 fallback_tick_.Cancel(); 235 fallback_tick_.Cancel();
173 fallback_tick_pending_ = false; 236 fallback_tick_pending_ = false;
174 } 237 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 const gfx::Rect& viewport_rect_for_tile_priority, 284 const gfx::Rect& viewport_rect_for_tile_priority,
222 const gfx::Transform& transform_for_tile_priority) { 285 const gfx::Transform& transform_for_tile_priority) {
223 DCHECK(CalledOnValidThread()); 286 DCHECK(CalledOnValidThread());
224 DCHECK(HasClient()); 287 DCHECK(HasClient());
225 DCHECK(context_provider_.get()); 288 DCHECK(context_provider_.get());
226 CancelFallbackTick(); 289 CancelFallbackTick();
227 290
228 surface_size_ = surface_size; 291 surface_size_ = surface_size;
229 client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority, 292 client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority,
230 transform_for_tile_priority); 293 transform_for_tile_priority);
231 const bool software_draw = false; 294 InvokeComposite(transform, viewport, clip);
232 InvokeComposite(transform, viewport, clip, software_draw);
233 } 295 }
234 296
235 void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) { 297 void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
236 DCHECK(CalledOnValidThread()); 298 DCHECK(CalledOnValidThread());
237 DCHECK(canvas); 299 DCHECK(canvas);
238 DCHECK(!current_sw_canvas_); 300 DCHECK(!current_sw_canvas_);
239 CancelFallbackTick(); 301 CancelFallbackTick();
240 302
241 base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas); 303 base::AutoReset<SkCanvas*> canvas_resetter(&current_sw_canvas_, canvas);
242 304
243 SkIRect canvas_clip; 305 SkIRect canvas_clip;
244 canvas->getClipDeviceBounds(&canvas_clip); 306 canvas->getClipDeviceBounds(&canvas_clip);
245 gfx::Rect clip = gfx::SkIRectToRect(canvas_clip); 307 gfx::Rect clip = gfx::SkIRectToRect(canvas_clip);
246 308
247 gfx::Transform transform(gfx::Transform::kSkipInitialization); 309 gfx::Transform transform(gfx::Transform::kSkipInitialization);
248 transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4. 310 transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4.
249 311
250 surface_size_ = gfx::Size(canvas->getBaseLayerSize().width(), 312 surface_size_ = gfx::Size(canvas->getBaseLayerSize().width(),
251 canvas->getBaseLayerSize().height()); 313 canvas->getBaseLayerSize().height());
252 const bool software_draw = true; 314 base::AutoReset<bool> set_in_software_draw(&in_software_draw_, true);
253 InvokeComposite(transform, clip, clip, software_draw); 315 InvokeComposite(transform, clip, clip);
254 } 316 }
255 317
256 void SynchronousCompositorOutputSurface::InvokeComposite( 318 void SynchronousCompositorOutputSurface::InvokeComposite(
257 const gfx::Transform& transform, 319 const gfx::Transform& transform,
258 const gfx::Rect& viewport, 320 const gfx::Rect& viewport,
259 const gfx::Rect& clip, 321 const gfx::Rect& clip) {
260 bool software_draw) {
261 gfx::Transform adjusted_transform = transform; 322 gfx::Transform adjusted_transform = transform;
262 adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0); 323 adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
263 did_swap_ = false; 324 did_swap_ = false;
264 client_->OnDraw(adjusted_transform, viewport, clip, software_draw); 325 client_->OnDraw(adjusted_transform, viewport, clip, in_software_draw_);
265 326
266 if (did_swap_) 327 if (did_swap_)
267 client_->DidSwapBuffersComplete(); 328 client_->DidSwapBuffersComplete();
268 } 329 }
269 330
270 void SynchronousCompositorOutputSurface::OnReclaimResources( 331 void SynchronousCompositorOutputSurface::OnReclaimResources(
271 uint32_t output_surface_id, 332 uint32_t output_surface_id,
272 const cc::CompositorFrameAck& ack) { 333 const cc::CompositorFrameAck& ack) {
273 // Ignore message if it's a stale one coming from a different output surface 334 // Ignore message if it's a stale one coming from a different output surface
274 // (e.g. after a lost context). 335 // (e.g. after a lost context).
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 379
319 bool SynchronousCompositorOutputSurface::Send(IPC::Message* message) { 380 bool SynchronousCompositorOutputSurface::Send(IPC::Message* message) {
320 DCHECK(CalledOnValidThread()); 381 DCHECK(CalledOnValidThread());
321 return sender_->Send(message); 382 return sender_->Send(message);
322 } 383 }
323 384
324 bool SynchronousCompositorOutputSurface::CalledOnValidThread() const { 385 bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
325 return thread_checker_.CalledOnValidThread(); 386 return thread_checker_.CalledOnValidThread();
326 } 387 }
327 388
389 void SynchronousCompositorOutputSurface::ReturnResources(
390 const cc::ReturnedResourceArray& resources) {
391 DCHECK(resources.empty());
392 cc::CompositorFrameAck ack;
393 client_->ReclaimResources(&ack);
394 }
395
396 void SynchronousCompositorOutputSurface::SetBeginFrameSource(
397 cc::BeginFrameSource* begin_frame_source) {
398 // Software output is synchronous and doesn't use a BeginFrameSource.
399 NOTREACHED();
400 }
401
328 } // namespace content 402 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/android/synchronous_compositor_output_surface.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698