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

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

Issue 2594843002: Implementing promise-based commit for driving OffscreenCanvas animations (Closed)
Patch Set: apply senorblanco feedback Created 3 years, 12 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 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/CrossThreadFunctional.h"
11 #include "platform/Histogram.h" 11 #include "platform/Histogram.h"
12 #include "platform/WebTaskRunner.h" 12 #include "platform/WebTaskRunner.h"
13 #include "platform/graphics/OffscreenCanvasPlaceholder.h" 13 #include "platform/graphics/OffscreenCanvasPlaceholder.h"
14 #include "platform/graphics/gpu/SharedGpuContext.h" 14 #include "platform/graphics/gpu/SharedGpuContext.h"
15 #include "public/platform/InterfaceProvider.h" 15 #include "public/platform/InterfaceProvider.h"
16 #include "public/platform/Platform.h" 16 #include "public/platform/Platform.h"
17 #include "public/platform/WebGraphicsContext3DProvider.h" 17 #include "public/platform/WebGraphicsContext3DProvider.h"
18 #include "public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom -blink.h" 18 #include "public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom -blink.h"
19 #include "third_party/khronos/GLES2/gl2.h" 19 #include "third_party/khronos/GLES2/gl2.h"
20 #include "third_party/khronos/GLES2/gl2ext.h" 20 #include "third_party/khronos/GLES2/gl2ext.h"
21 #include "third_party/skia/include/core/SkColor.h" 21 #include "third_party/skia/include/core/SkColor.h"
22 #include "third_party/skia/include/core/SkImage.h" 22 #include "third_party/skia/include/core/SkImage.h"
23 #include "ui/gfx/geometry/rect.h" 23 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gfx/transform.h" 24 #include "ui/gfx/transform.h"
25 #include "wtf/typed_arrays/ArrayBuffer.h" 25 #include "wtf/typed_arrays/ArrayBuffer.h"
26 #include "wtf/typed_arrays/Uint8Array.h" 26 #include "wtf/typed_arrays/Uint8Array.h"
27 27
28 namespace blink { 28 namespace blink {
29 29
30 // This constant specifies the maximum number of pixel buffer that are allowed
31 // to co-exist at a given time. The minimum number is 2 (double buffered).
32 // larger numbers can help maintain a steadier frame rates, but they increase
33 // latency.
34 const int kMaximumOffscreenCanvasBufferCount = 3;
35
30 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( 36 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl(
37 OffscreenCanvasFrameDispatcherClient* client,
31 uint32_t clientId, 38 uint32_t clientId,
32 uint32_t sinkId, 39 uint32_t sinkId,
33 int canvasId, 40 int canvasId,
34 int width, 41 int width,
35 int height) 42 int height)
36 : m_frameSinkId(cc::FrameSinkId(clientId, sinkId)), 43 : OffscreenCanvasFrameDispatcher(client),
44 m_frameSinkId(cc::FrameSinkId(clientId, sinkId)),
37 m_width(width), 45 m_width(width),
38 m_height(height), 46 m_height(height),
39 m_nextResourceId(1u), 47 m_nextResourceId(1u),
40 m_binding(this), 48 m_binding(this),
41 m_placeholderCanvasId(canvasId) { 49 m_placeholderCanvasId(canvasId) {
42 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); 50 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId();
43 DCHECK(!m_sink.is_bound()); 51 DCHECK(!m_sink.is_bound());
44 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; 52 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider;
45 Platform::current()->interfaceProvider()->getInterface( 53 Platform::current()->interfaceProvider()->getInterface(
46 mojo::MakeRequest(&provider)); 54 mojo::MakeRequest(&provider));
47 provider->CreateCompositorFrameSink(m_frameSinkId, 55 provider->CreateCompositorFrameSink(m_frameSinkId,
48 m_binding.CreateInterfacePtrAndBind(), 56 m_binding.CreateInterfacePtrAndBind(),
49 mojo::MakeRequest(&m_sink)); 57 mojo::MakeRequest(&m_sink));
50 } 58 }
51 59
60 OffscreenCanvasFrameDispatcherImpl::~OffscreenCanvasFrameDispatcherImpl() {
61 m_syntheticBeginFrameTask.cancel();
62 }
63
52 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( 64 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap(
53 cc::TransferableResource& resource, 65 cc::TransferableResource& resource,
54 RefPtr<StaticBitmapImage> image) { 66 RefPtr<StaticBitmapImage> image) {
55 std::unique_ptr<cc::SharedBitmap> bitmap = 67 std::unique_ptr<cc::SharedBitmap> bitmap =
56 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); 68 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height));
57 if (!bitmap) 69 if (!bitmap)
58 return; 70 return;
59 unsigned char* pixels = bitmap->pixels(); 71 unsigned char* pixels = bitmap->pixels();
60 DCHECK(pixels); 72 DCHECK(pixels);
61 SkImageInfo imageInfo = SkImageInfo::Make( 73 SkImageInfo imageInfo = SkImageInfo::Make(
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } 182 }
171 } 183 }
172 184
173 } // namespace 185 } // namespace
174 186
175 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( 187 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame(
176 RefPtr<StaticBitmapImage> image, 188 RefPtr<StaticBitmapImage> image,
177 double commitStartTime, 189 double commitStartTime,
178 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is 190 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is
179 called on SwiftShader. */) { 191 called on SwiftShader. */) {
180 if (!image) 192 if (!image || !verifyImageSize(image->size()))
181 return;
182 if (!verifyImageSize(image->size()))
183 return; 193 return;
184 cc::CompositorFrame frame; 194 cc::CompositorFrame frame;
185 // TODO(crbug.com/652931): update the device_scale_factor 195 // TODO(crbug.com/652931): update the device_scale_factor
186 frame.metadata.device_scale_factor = 1.0f; 196 frame.metadata.device_scale_factor = 1.0f;
187 197
188 const gfx::Rect bounds(m_width, m_height); 198 const gfx::Rect bounds(m_width, m_height);
189 const int renderPassId = 1; 199 const int renderPassId = 1;
190 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); 200 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
191 pass->SetNew(renderPassId, bounds, bounds, gfx::Transform()); 201 pass->SetNew(renderPassId, bounds, bounds, gfx::Transform());
192 pass->has_transparent_background = false; 202 pass->has_transparent_background = false;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 0, 10000000, 50)); 361 0, 10000000, 50));
352 commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * 362 commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime *
353 1000000.0); 363 1000000.0);
354 } 364 }
355 break; 365 break;
356 case OffscreenCanvasCommitTypeCount: 366 case OffscreenCanvasCommitTypeCount:
357 NOTREACHED(); 367 NOTREACHED();
358 } 368 }
359 369
360 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame)); 370 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame));
371
372 // TODO(crbug.com/674744): Get BeginFrame to fire on its own.
373 scheduleSyntheticBeginFrame();
374 }
375
376 void OffscreenCanvasFrameDispatcherImpl::scheduleSyntheticBeginFrame() {
377 m_syntheticBeginFrameTask =
378 Platform::current()
379 ->currentThread()
380 ->getWebTaskRunner()
381 ->postDelayedCancellableTask(
382 BLINK_FROM_HERE,
383 WTF::bind(&OffscreenCanvasFrameDispatcherImpl::OnBeginFrame,
384 WTF::unretained(this), cc::BeginFrameArgs()),
385 16);
361 } 386 }
362 387
363 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { 388 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() {
364 // TODO(fsamuel): Implement this. 389 // TODO(fsamuel): Implement this.
365 } 390 }
366 391
367 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( 392 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame(
368 const cc::BeginFrameArgs& beginFrameArgs) {} 393 const cc::BeginFrameArgs& beginFrameArgs) {
394 if (!client())
395 return;
396 unsigned framesInFlight = m_cachedImages.size() + m_sharedBitmaps.size() +
397 m_cachedTextureIds.size();
398
399 // Limit the rate of compositor commits.
400 if (framesInFlight < kMaximumOffscreenCanvasBufferCount) {
401 client()->beginFrame();
402 } else {
403 // TODO(crbug.com/674744): Get BeginFrame to fire on its own.
404 // The following call is to reschedule the frame in cases where we encounter
405 // a backlog.
406 scheduleSyntheticBeginFrame();
407 }
408 }
369 409
370 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( 410 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources(
371 const cc::ReturnedResourceArray& resources) { 411 const cc::ReturnedResourceArray& resources) {
372 for (const auto& resource : resources) { 412 for (const auto& resource : resources) {
373 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); 413 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id);
374 if (image) 414 if (image)
375 image->updateSyncToken(resource.sync_token); 415 image->updateSyncToken(resource.sync_token);
376 reclaimResource(resource.id); 416 reclaimResource(resource.id);
377 } 417 }
378 } 418 }
379 419
380 void OffscreenCanvasFrameDispatcherImpl::WillDrawSurface() { 420 void OffscreenCanvasFrameDispatcherImpl::WillDrawSurface() {
381 // TODO(fsamuel, staraz): Implement this. 421 // TODO(fsamuel, staraz): Implement this.
382 NOTIMPLEMENTED();
383 } 422 }
384 423
385 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) { 424 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) {
386 // An image resource needs to be returned by both the 425 // An image resource needs to be returned by both the
387 // CompositorFrameSink and the HTMLCanvasElement. These 426 // CompositorFrameSink and the HTMLCanvasElement. These
388 // events can happen in any order. The first of the two 427 // events can happen in any order. The first of the two
389 // to return a given resource will result in the spare 428 // to return a given resource will result in the spare
390 // resource lock being lifted, and the second will delete 429 // resource lock being lifted, and the second will delete
391 // the resource for real. 430 // the resource for real.
392 if (m_spareResourceLocks.contains(resourceId)) { 431 if (m_spareResourceLocks.contains(resourceId)) {
(...skipping 11 matching lines...) Expand all
404 return true; 443 return true;
405 return false; 444 return false;
406 } 445 }
407 446
408 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) { 447 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) {
409 m_width = width; 448 m_width = width;
410 m_height = height; 449 m_height = height;
411 } 450 }
412 451
413 } // namespace blink 452 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698