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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp

Issue 2493673002: Synchronize OffscreenCanvas content with the placeholder canvas (Closed)
Patch Set: fix obsolete test Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "platform/graphics/OffscreenCanvasFrameDispatcherImpl.h" 5 #include "platform/graphics/OffscreenCanvasFrameDispatcherImpl.h"
6 6
7 #include "cc/output/compositor_frame.h" 7 #include "cc/output/compositor_frame.h"
8 #include "cc/quads/texture_draw_quad.h" 8 #include "cc/quads/texture_draw_quad.h"
9 #include "gpu/command_buffer/client/gles2_interface.h" 9 #include "gpu/command_buffer/client/gles2_interface.h"
10 #include "platform/CrossThreadFunctional.h"
10 #include "platform/Histogram.h" 11 #include "platform/Histogram.h"
12 #include "platform/WebTaskRunner.h"
13 #include "platform/graphics/OffscreenCanvasPlaceholder.h"
11 #include "platform/graphics/gpu/SharedGpuContext.h" 14 #include "platform/graphics/gpu/SharedGpuContext.h"
12 #include "public/platform/InterfaceProvider.h" 15 #include "public/platform/InterfaceProvider.h"
13 #include "public/platform/Platform.h" 16 #include "public/platform/Platform.h"
14 #include "public/platform/WebGraphicsContext3DProvider.h" 17 #include "public/platform/WebGraphicsContext3DProvider.h"
15 #include "public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom -blink.h" 18 #include "public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom -blink.h"
16 #include "third_party/khronos/GLES2/gl2.h" 19 #include "third_party/khronos/GLES2/gl2.h"
17 #include "third_party/khronos/GLES2/gl2ext.h" 20 #include "third_party/khronos/GLES2/gl2ext.h"
18 #include "third_party/skia/include/core/SkColor.h" 21 #include "third_party/skia/include/core/SkColor.h"
19 #include "third_party/skia/include/core/SkImage.h" 22 #include "third_party/skia/include/core/SkImage.h"
20 #include "ui/gfx/geometry/rect.h" 23 #include "ui/gfx/geometry/rect.h"
21 #include "ui/gfx/transform.h" 24 #include "ui/gfx/transform.h"
22 #include "wtf/typed_arrays/ArrayBuffer.h" 25 #include "wtf/typed_arrays/ArrayBuffer.h"
23 #include "wtf/typed_arrays/Uint8Array.h" 26 #include "wtf/typed_arrays/Uint8Array.h"
24 27
25 namespace blink { 28 namespace blink {
26 29
27 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( 30 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl(
28 uint32_t clientId, 31 uint32_t clientId,
29 uint32_t sinkId, 32 uint32_t sinkId,
30 uint32_t localId, 33 uint32_t localId,
31 uint64_t nonceHigh, 34 uint64_t nonceHigh,
32 uint64_t nonceLow, 35 uint64_t nonceLow,
36 int canvasId,
33 int width, 37 int width,
34 int height) 38 int height)
35 : m_surfaceId( 39 : m_surfaceId(
36 cc::FrameSinkId(clientId, sinkId), 40 cc::FrameSinkId(clientId, sinkId),
37 cc::LocalFrameId( 41 cc::LocalFrameId(
38 localId, 42 localId,
39 base::UnguessableToken::Deserialize(nonceHigh, nonceLow))), 43 base::UnguessableToken::Deserialize(nonceHigh, nonceLow))),
40 m_width(width), 44 m_width(width),
41 m_height(height), 45 m_height(height),
42 m_nextResourceId(1u), 46 m_nextResourceId(1u),
43 m_binding(this) { 47 m_binding(this),
48 m_placeholderCanvasId(canvasId) {
44 DCHECK(!m_sink.is_bound()); 49 DCHECK(!m_sink.is_bound());
45 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; 50 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider;
46 Platform::current()->interfaceProvider()->getInterface( 51 Platform::current()->interfaceProvider()->getInterface(
47 mojo::GetProxy(&provider)); 52 mojo::GetProxy(&provider));
48 provider->CreateCompositorFrameSink(m_surfaceId, 53 provider->CreateCompositorFrameSink(m_surfaceId,
49 m_binding.CreateInterfacePtrAndBind(), 54 m_binding.CreateInterfacePtrAndBind(),
50 mojo::GetProxy(&m_sink)); 55 mojo::GetProxy(&m_sink));
51 } 56 }
52 57
53 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( 58 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap(
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 resource.mailbox_holder = 148 resource.mailbox_holder =
144 gpu::MailboxHolder(image->mailbox(), image->syncToken(), GL_TEXTURE_2D); 149 gpu::MailboxHolder(image->mailbox(), image->syncToken(), GL_TEXTURE_2D);
145 resource.read_lock_fences_enabled = false; 150 resource.read_lock_fences_enabled = false;
146 resource.is_software = false; 151 resource.is_software = false;
147 152
148 // Hold ref to |image|, to keep it alive until the browser ReclaimResources. 153 // Hold ref to |image|, to keep it alive until the browser ReclaimResources.
149 // It guarantees that the resource is not re-used or deleted. 154 // It guarantees that the resource is not re-used or deleted.
150 m_cachedImages.add(m_nextResourceId, std::move(image)); 155 m_cachedImages.add(m_nextResourceId, std::move(image));
151 } 156 }
152 157
158 namespace {
159
160 void updatePlaceholderImage(WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher,
161 std::unique_ptr<WebTaskRunner> taskRunner,
162 int placeholderCanvasId,
163 RefPtr<blink::Image> image,
164 unsigned resourceId) {
165 DCHECK(isMainThread());
166 OffscreenCanvasPlaceholder* placeholderCanvas =
167 OffscreenCanvasPlaceholder::getPlaceholderById(placeholderCanvasId);
168 if (placeholderCanvas) {
169 placeholderCanvas->setPlaceholderFrame(std::move(image),
170 std::move(dispatcher),
171 std::move(taskRunner), resourceId);
172 }
173 }
174
175 } // namespace
176
153 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( 177 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame(
154 RefPtr<StaticBitmapImage> image, 178 RefPtr<StaticBitmapImage> image,
155 double commitStartTime, 179 double commitStartTime,
156 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is 180 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is
157 called on SwiftShader. */) { 181 called on SwiftShader. */) {
158 if (!image) 182 if (!image)
159 return; 183 return;
160 if (!verifyImageSize(image->size())) 184 if (!verifyImageSize(image->size()))
161 return; 185 return;
162 cc::CompositorFrame frame; 186 cc::CompositorFrame frame;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 !isWebGLSoftwareRendering) { 232 !isWebGLSoftwareRendering) {
209 // Case 3: canvas is not gpu-accelerated, but compositor is 233 // Case 3: canvas is not gpu-accelerated, but compositor is
210 commitType = CommitSoftwareCanvasGPUCompositing; 234 commitType = CommitSoftwareCanvasGPUCompositing;
211 setTransferableResourceToSharedGPUContext(resource, image); 235 setTransferableResourceToSharedGPUContext(resource, image);
212 } else { 236 } else {
213 // Case 4: both canvas and compositor are not gpu accelerated. 237 // Case 4: both canvas and compositor are not gpu accelerated.
214 commitType = CommitSoftwareCanvasSoftwareCompositing; 238 commitType = CommitSoftwareCanvasSoftwareCompositing;
215 setTransferableResourceToSharedBitmap(resource, image); 239 setTransferableResourceToSharedBitmap(resource, image);
216 } 240 }
217 } 241 }
242
243 // After this point, |image| can only be used on the main thread, until
244 // it is returned.
245 image->transfer();
246 std::unique_ptr<WebTaskRunner> dispatcherTaskRunner =
247 Platform::current()->currentThread()->getWebTaskRunner()->clone();
248
249 Platform::current()->mainThread()->getWebTaskRunner()->postTask(
250 BLINK_FROM_HERE,
251 crossThreadBind(updatePlaceholderImage, this->createWeakPtr(),
252 passed(std::move(dispatcherTaskRunner)),
253 m_placeholderCanvasId, std::move(image), resource.id));
254 m_spareResourceLocks.add(m_nextResourceId);
255
218 commitTypeHistogram.count(commitType); 256 commitTypeHistogram.count(commitType);
219 257
220 m_nextResourceId++; 258 m_nextResourceId++;
221 frame.resource_list.push_back(std::move(resource)); 259 frame.resource_list.push_back(std::move(resource));
222 260
223 cc::TextureDrawQuad* quad = 261 cc::TextureDrawQuad* quad =
224 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); 262 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
225 gfx::Size rectSize(m_width, m_height); 263 gfx::Size rectSize(m_width, m_height);
226 264
227 const bool needsBlending = true; 265 const bool needsBlending = true;
228 // TOOD(crbug.com/645993): this should be inherited from WebGL context's 266 // TOOD(crbug.com/645993): this should be inherited from WebGL context's
229 // creation settings. 267 // creation settings.
230 const bool premultipliedAlpha = true; 268 const bool premultipliedAlpha = true;
231 const gfx::PointF uvTopLeft(0.f, 0.f); 269 const gfx::PointF uvTopLeft(0.f, 0.f);
232 const gfx::PointF uvBottomRight(1.f, 1.f); 270 const gfx::PointF uvBottomRight(1.f, 1.f);
233 float vertexOpacity[4] = {1.f, 1.f, 1.f, 1.f}; 271 float vertexOpacity[4] = {1.f, 1.f, 1.f, 1.f};
234 // TODO(crbug.com/645994): this should be true when using style 272 // TODO(crbug.com/645994): this should be true when using style
235 // "image-rendering: pixelated". 273 // "image-rendering: pixelated".
236 const bool nearestNeighbor = false; 274 const bool nearestNeighbor = false;
237 quad->SetAll(sqs, bounds, bounds, bounds, needsBlending, resource.id, 275 quad->SetAll(sqs, bounds, bounds, bounds, needsBlending, resource.id,
238 gfx::Size(), premultipliedAlpha, uvTopLeft, uvBottomRight, 276 gfx::Size(), premultipliedAlpha, uvTopLeft, uvBottomRight,
239 SK_ColorTRANSPARENT, vertexOpacity, yflipped, nearestNeighbor, 277 SK_ColorTRANSPARENT, vertexOpacity, yflipped, nearestNeighbor,
240 false); 278 false);
241 279
242 frame.render_pass_list.push_back(std::move(pass)); 280 frame.render_pass_list.push_back(std::move(pass));
243 281
244 double elapsedTime = WTF::monotonicallyIncreasingTime() - commitStartTime; 282 double elapsedTime = WTF::monotonicallyIncreasingTime() - commitStartTime;
283
284 // TODO(crbug.com/663916): The off-main-thread metrics are commented-out
285 // because they cause thread check errors (static variable accessed in many
286 // threads)
245 switch (commitType) { 287 switch (commitType) {
246 case CommitGPUCanvasGPUCompositing: 288 case CommitGPUCanvasGPUCompositing:
247 if (isMainThread()) { 289 if (isMainThread()) {
248 DEFINE_STATIC_LOCAL( 290 DEFINE_STATIC_LOCAL(
249 CustomCountHistogram, commitGPUCanvasGPUCompositingMainTimer, 291 CustomCountHistogram, commitGPUCanvasGPUCompositingMainTimer,
250 ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingMain", 0, 292 ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingMain", 0,
251 10000000, 50)); 293 10000000, 50));
252 commitGPUCanvasGPUCompositingMainTimer.count(elapsedTime * 1000000.0); 294 commitGPUCanvasGPUCompositingMainTimer.count(elapsedTime * 1000000.0);
253 } else { 295 } /* else {
254 DEFINE_STATIC_LOCAL( 296 DEFINE_STATIC_LOCAL(
255 CustomCountHistogram, commitGPUCanvasGPUCompositingWorkerTimer, 297 CustomCountHistogram, commitGPUCanvasGPUCompositingWorkerTimer,
256 ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingWorker", 0, 298 ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingWorker", 0,
257 10000000, 50)); 299 10000000, 50));
258 commitGPUCanvasGPUCompositingWorkerTimer.count(elapsedTime * 1000000.0); 300 commitGPUCanvasGPUCompositingWorkerTimer.count(elapsedTime * 1000000.0);
259 } 301 } */
260 break; 302 break;
261 case CommitGPUCanvasSoftwareCompositing: 303 case CommitGPUCanvasSoftwareCompositing:
262 if (isMainThread()) { 304 if (isMainThread()) {
263 DEFINE_STATIC_LOCAL( 305 DEFINE_STATIC_LOCAL(
264 CustomCountHistogram, commitGPUCanvasSoftwareCompositingMainTimer, 306 CustomCountHistogram, commitGPUCanvasSoftwareCompositingMainTimer,
265 ("Blink.Canvas.OffscreenCommit.GPUCanvasSoftwareCompositingMain", 0, 307 ("Blink.Canvas.OffscreenCommit.GPUCanvasSoftwareCompositingMain", 0,
266 10000000, 50)); 308 10000000, 50));
267 commitGPUCanvasSoftwareCompositingMainTimer.count(elapsedTime * 309 commitGPUCanvasSoftwareCompositingMainTimer.count(elapsedTime *
268 1000000.0); 310 1000000.0);
269 } else { 311 } /* else {
270 DEFINE_STATIC_LOCAL( 312 DEFINE_STATIC_LOCAL(
271 CustomCountHistogram, commitGPUCanvasSoftwareCompositingWorkerTimer, 313 CustomCountHistogram, commitGPUCanvasSoftwareCompositingWorkerTimer,
272 ("Blink.Canvas.OffscreenCommit.GPUCanvasSoftwareCompositingWorker", 314 ("Blink.Canvas.OffscreenCommit.GPUCanvasSoftwareCompositingWorker",
273 0, 10000000, 50)); 315 0, 10000000, 50));
274 commitGPUCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * 316 commitGPUCanvasSoftwareCompositingWorkerTimer.count(elapsedTime *
275 1000000.0); 317 1000000.0);
276 } 318 } */
277 break; 319 break;
278 case CommitSoftwareCanvasGPUCompositing: 320 case CommitSoftwareCanvasGPUCompositing:
279 if (isMainThread()) { 321 if (isMainThread()) {
280 DEFINE_STATIC_LOCAL( 322 DEFINE_STATIC_LOCAL(
281 CustomCountHistogram, commitSoftwareCanvasGPUCompositingMainTimer, 323 CustomCountHistogram, commitSoftwareCanvasGPUCompositingMainTimer,
282 ("Blink.Canvas.OffscreenCommit.SoftwareCanvasGPUCompositingMain", 0, 324 ("Blink.Canvas.OffscreenCommit.SoftwareCanvasGPUCompositingMain", 0,
283 10000000, 50)); 325 10000000, 50));
284 commitSoftwareCanvasGPUCompositingMainTimer.count(elapsedTime * 326 commitSoftwareCanvasGPUCompositingMainTimer.count(elapsedTime *
285 1000000.0); 327 1000000.0);
286 } else { 328 } /* else {
287 DEFINE_STATIC_LOCAL( 329 DEFINE_STATIC_LOCAL(
288 CustomCountHistogram, commitSoftwareCanvasGPUCompositingWorkerTimer, 330 CustomCountHistogram, commitSoftwareCanvasGPUCompositingWorkerTimer,
289 ("Blink.Canvas.OffscreenCommit.SoftwareCanvasGPUCompositingWorker", 331 ("Blink.Canvas.OffscreenCommit.SoftwareCanvasGPUCompositingWorker",
290 0, 10000000, 50)); 332 0, 10000000, 50));
291 commitSoftwareCanvasGPUCompositingWorkerTimer.count(elapsedTime * 333 commitSoftwareCanvasGPUCompositingWorkerTimer.count(elapsedTime *
292 1000000.0); 334 1000000.0);
293 } 335 } */
294 break; 336 break;
295 case CommitSoftwareCanvasSoftwareCompositing: 337 case CommitSoftwareCanvasSoftwareCompositing:
296 if (isMainThread()) { 338 if (isMainThread()) {
297 DEFINE_STATIC_LOCAL(CustomCountHistogram, 339 DEFINE_STATIC_LOCAL(CustomCountHistogram,
298 commitSoftwareCanvasSoftwareCompositingMainTimer, 340 commitSoftwareCanvasSoftwareCompositingMainTimer,
299 ("Blink.Canvas.OffscreenCommit." 341 ("Blink.Canvas.OffscreenCommit."
300 "SoftwareCanvasSoftwareCompositingMain", 342 "SoftwareCanvasSoftwareCompositingMain",
301 0, 10000000, 50)); 343 0, 10000000, 50));
302 commitSoftwareCanvasSoftwareCompositingMainTimer.count(elapsedTime * 344 commitSoftwareCanvasSoftwareCompositingMainTimer.count(elapsedTime *
303 1000000.0); 345 1000000.0);
304 } else { 346 } /* else {
305 DEFINE_STATIC_LOCAL(CustomCountHistogram, 347 DEFINE_STATIC_LOCAL(CustomCountHistogram,
306 commitSoftwareCanvasSoftwareCompositingWorkerTimer, 348 commitSoftwareCanvasSoftwareCompositingWorkerTimer,
307 ("Blink.Canvas.OffscreenCommit." 349 ("Blink.Canvas.OffscreenCommit."
308 "SoftwareCanvasSoftwareCompositingWorker", 350 "SoftwareCanvasSoftwareCompositingWorker",
309 0, 10000000, 50)); 351 0, 10000000, 50));
310 commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * 352 commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime *
311 1000000.0); 353 1000000.0);
312 } 354 } */
313 break; 355 break;
314 case OffscreenCanvasCommitTypeCount: 356 case OffscreenCanvasCommitTypeCount:
315 NOTREACHED(); 357 NOTREACHED();
316 } 358 }
317 359
318 m_sink->SubmitCompositorFrame(std::move(frame)); 360 m_sink->SubmitCompositorFrame(std::move(frame));
319 } 361 }
320 362
321 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { 363 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() {
322 // TODO(fsamuel): Implement this. 364 // TODO(fsamuel): Implement this.
323 } 365 }
324 366
325 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( 367 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame(
326 const cc::BeginFrameArgs& beginFrameArgs) {} 368 const cc::BeginFrameArgs& beginFrameArgs) {}
327 369
328 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( 370 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources(
329 const cc::ReturnedResourceArray& resources) { 371 const cc::ReturnedResourceArray& resources) {
330 for (const auto& resource : resources) { 372 for (const auto& resource : resources) {
331 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); 373 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id);
332 if (image) 374 if (image)
333 image->updateSyncToken(resource.sync_token); 375 image->updateSyncToken(resource.sync_token);
334 m_cachedImages.remove(resource.id); 376 reclaimResource(resource.id);
335 m_sharedBitmaps.remove(resource.id);
336 m_cachedTextureIds.remove(resource.id);
337 } 377 }
338 } 378 }
339 379
380 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) {
381 // An image resource needs to be returned by both the
382 // CompositorFrameSink and the HTMLCanvasElement. These
383 // events can happen in any order. The first of the two
384 // to return a given resource will result in the spare
385 // resource lock being lifted, and the second will delete
386 // the resource for real.
387 if (m_spareResourceLocks.contains(resourceId)) {
388 m_spareResourceLocks.remove(resourceId);
389 return;
390 }
391 m_cachedImages.remove(resourceId);
392 m_sharedBitmaps.remove(resourceId);
393 m_cachedTextureIds.remove(resourceId);
394 }
395
340 bool OffscreenCanvasFrameDispatcherImpl::verifyImageSize( 396 bool OffscreenCanvasFrameDispatcherImpl::verifyImageSize(
341 const IntSize imageSize) { 397 const IntSize imageSize) {
342 if (imageSize.width() == m_width && imageSize.height() == m_height) 398 if (imageSize.width() == m_width && imageSize.height() == m_height)
343 return true; 399 return true;
344 return false; 400 return false;
345 } 401 }
346 402
347 } // namespace blink 403 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698