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

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: rebase Created 3 years, 11 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 | « third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.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 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_changeSizeForNextCommit(false), 47 m_changeSizeForNextCommit(false),
40 m_nextResourceId(1u), 48 m_nextResourceId(1u),
41 m_binding(this), 49 m_binding(this),
42 m_placeholderCanvasId(canvasId) { 50 m_placeholderCanvasId(canvasId) {
43 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); 51 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId();
44 DCHECK(!m_sink.is_bound()); 52 DCHECK(!m_sink.is_bound());
45 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; 53 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider;
46 Platform::current()->interfaceProvider()->getInterface( 54 Platform::current()->interfaceProvider()->getInterface(
47 mojo::MakeRequest(&provider)); 55 mojo::MakeRequest(&provider));
48 provider->CreateCompositorFrameSink(m_frameSinkId, 56 provider->CreateCompositorFrameSink(m_frameSinkId,
49 m_binding.CreateInterfacePtrAndBind(), 57 m_binding.CreateInterfacePtrAndBind(),
50 mojo::MakeRequest(&m_sink)); 58 mojo::MakeRequest(&m_sink));
51 } 59 }
52 60
61 OffscreenCanvasFrameDispatcherImpl::~OffscreenCanvasFrameDispatcherImpl() {
62 m_syntheticBeginFrameTask.cancel();
63 }
64
53 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( 65 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap(
54 cc::TransferableResource& resource, 66 cc::TransferableResource& resource,
55 RefPtr<StaticBitmapImage> image) { 67 RefPtr<StaticBitmapImage> image) {
56 std::unique_ptr<cc::SharedBitmap> bitmap = 68 std::unique_ptr<cc::SharedBitmap> bitmap =
57 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); 69 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height));
58 if (!bitmap) 70 if (!bitmap)
59 return; 71 return;
60 unsigned char* pixels = bitmap->pixels(); 72 unsigned char* pixels = bitmap->pixels();
61 DCHECK(pixels); 73 DCHECK(pixels);
62 SkImageInfo imageInfo = SkImageInfo::Make( 74 SkImageInfo imageInfo = SkImageInfo::Make(
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 } 183 }
172 } 184 }
173 185
174 } // namespace 186 } // namespace
175 187
176 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( 188 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame(
177 RefPtr<StaticBitmapImage> image, 189 RefPtr<StaticBitmapImage> image,
178 double commitStartTime, 190 double commitStartTime,
179 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is 191 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is
180 called on SwiftShader. */) { 192 called on SwiftShader. */) {
181 if (!image) 193 if (!image || !verifyImageSize(image->size()))
182 return;
183 if (!verifyImageSize(image->size()))
184 return; 194 return;
185 cc::CompositorFrame frame; 195 cc::CompositorFrame frame;
186 // TODO(crbug.com/652931): update the device_scale_factor 196 // TODO(crbug.com/652931): update the device_scale_factor
187 frame.metadata.device_scale_factor = 1.0f; 197 frame.metadata.device_scale_factor = 1.0f;
188 198
189 const gfx::Rect bounds(m_width, m_height); 199 const gfx::Rect bounds(m_width, m_height);
190 const int renderPassId = 1; 200 const int renderPassId = 1;
191 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); 201 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
192 pass->SetNew(renderPassId, bounds, bounds, gfx::Transform()); 202 pass->SetNew(renderPassId, bounds, bounds, gfx::Transform());
193 pass->has_transparent_background = false; 203 pass->has_transparent_background = false;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 break; 366 break;
357 case OffscreenCanvasCommitTypeCount: 367 case OffscreenCanvasCommitTypeCount:
358 NOTREACHED(); 368 NOTREACHED();
359 } 369 }
360 370
361 if (m_changeSizeForNextCommit) { 371 if (m_changeSizeForNextCommit) {
362 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); 372 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId();
363 m_changeSizeForNextCommit = false; 373 m_changeSizeForNextCommit = false;
364 } 374 }
365 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame)); 375 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame));
376
377 // TODO(crbug.com/674744): Get BeginFrame to fire on its own.
378 scheduleSyntheticBeginFrame();
379 }
380
381 void OffscreenCanvasFrameDispatcherImpl::scheduleSyntheticBeginFrame() {
382 m_syntheticBeginFrameTask =
383 Platform::current()
384 ->currentThread()
385 ->getWebTaskRunner()
386 ->postDelayedCancellableTask(
387 BLINK_FROM_HERE,
388 WTF::bind(&OffscreenCanvasFrameDispatcherImpl::OnBeginFrame,
389 WTF::unretained(this), cc::BeginFrameArgs()),
390 16);
366 } 391 }
367 392
368 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { 393 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() {
369 // TODO(fsamuel): Implement this. 394 // TODO(fsamuel): Implement this.
370 } 395 }
371 396
372 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( 397 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame(
373 const cc::BeginFrameArgs& beginFrameArgs) {} 398 const cc::BeginFrameArgs& beginFrameArgs) {
399 if (!client())
400 return;
401 unsigned framesInFlight = m_cachedImages.size() + m_sharedBitmaps.size() +
402 m_cachedTextureIds.size();
403
404 // Limit the rate of compositor commits.
405 if (framesInFlight < kMaximumOffscreenCanvasBufferCount) {
406 client()->beginFrame();
407 } else {
408 // TODO(crbug.com/674744): Get BeginFrame to fire on its own.
409 // The following call is to reschedule the frame in cases where we encounter
410 // a backlog.
411 scheduleSyntheticBeginFrame();
412 }
413 }
374 414
375 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( 415 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources(
376 const cc::ReturnedResourceArray& resources) { 416 const cc::ReturnedResourceArray& resources) {
377 for (const auto& resource : resources) { 417 for (const auto& resource : resources) {
378 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); 418 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id);
379 if (image) 419 if (image)
380 image->updateSyncToken(resource.sync_token); 420 image->updateSyncToken(resource.sync_token);
381 reclaimResource(resource.id); 421 reclaimResource(resource.id);
382 } 422 }
383 } 423 }
384 424
385 void OffscreenCanvasFrameDispatcherImpl::WillDrawSurface() { 425 void OffscreenCanvasFrameDispatcherImpl::WillDrawSurface() {
386 // TODO(fsamuel, staraz): Implement this. 426 // TODO(fsamuel, staraz): Implement this.
387 NOTIMPLEMENTED();
388 } 427 }
389 428
390 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) { 429 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) {
391 // An image resource needs to be returned by both the 430 // An image resource needs to be returned by both the
392 // CompositorFrameSink and the HTMLCanvasElement. These 431 // CompositorFrameSink and the HTMLCanvasElement. These
393 // events can happen in any order. The first of the two 432 // events can happen in any order. The first of the two
394 // to return a given resource will result in the spare 433 // to return a given resource will result in the spare
395 // resource lock being lifted, and the second will delete 434 // resource lock being lifted, and the second will delete
396 // the resource for real. 435 // the resource for real.
397 if (m_spareResourceLocks.contains(resourceId)) { 436 if (m_spareResourceLocks.contains(resourceId)) {
(...skipping 14 matching lines...) Expand all
412 451
413 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) { 452 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) {
414 if (m_width != width || m_height != height) { 453 if (m_width != width || m_height != height) {
415 m_width = width; 454 m_width = width;
416 m_height = height; 455 m_height = height;
417 m_changeSizeForNextCommit = true; 456 m_changeSizeForNextCommit = true;
418 } 457 }
419 } 458 }
420 459
421 } // namespace blink 460 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698