OLD | NEW |
---|---|
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 | |
36 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( | 30 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( |
37 OffscreenCanvasFrameDispatcherClient* client, | 31 OffscreenCanvasFrameDispatcherClient* client, |
38 uint32_t clientId, | 32 uint32_t clientId, |
39 uint32_t sinkId, | 33 uint32_t sinkId, |
40 int canvasId, | 34 int canvasId, |
41 int width, | 35 int width, |
42 int height) | 36 int height) |
43 : OffscreenCanvasFrameDispatcher(client), | 37 : OffscreenCanvasFrameDispatcher(client), |
44 m_frameSinkId(cc::FrameSinkId(clientId, sinkId)), | 38 m_frameSinkId(cc::FrameSinkId(clientId, sinkId)), |
45 m_width(width), | 39 m_width(width), |
46 m_height(height), | 40 m_height(height), |
47 m_changeSizeForNextCommit(false), | 41 m_changeSizeForNextCommit(false), |
42 m_needsBeginFrame(false), | |
48 m_nextResourceId(1u), | 43 m_nextResourceId(1u), |
49 m_binding(this), | 44 m_binding(this), |
50 m_placeholderCanvasId(canvasId) { | 45 m_placeholderCanvasId(canvasId) { |
51 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); | 46 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); |
52 DCHECK(!m_sink.is_bound()); | 47 DCHECK(!m_sink.is_bound()); |
53 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; | 48 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; |
54 Platform::current()->interfaceProvider()->getInterface( | 49 Platform::current()->interfaceProvider()->getInterface( |
55 mojo::MakeRequest(&provider)); | 50 mojo::MakeRequest(&provider)); |
56 provider->CreateCompositorFrameSink(m_frameSinkId, | 51 provider->CreateCompositorFrameSink(m_frameSinkId, |
57 m_binding.CreateInterfacePtrAndBind(), | 52 m_binding.CreateInterfacePtrAndBind(), |
58 mojo::MakeRequest(&m_sink)); | 53 mojo::MakeRequest(&m_sink)); |
59 } | 54 } |
60 | 55 |
61 OffscreenCanvasFrameDispatcherImpl::~OffscreenCanvasFrameDispatcherImpl() { | 56 OffscreenCanvasFrameDispatcherImpl::~OffscreenCanvasFrameDispatcherImpl() { |
62 m_syntheticBeginFrameTask.cancel(); | |
63 } | 57 } |
64 | 58 |
65 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( | 59 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( |
66 cc::TransferableResource& resource, | 60 cc::TransferableResource& resource, |
67 RefPtr<StaticBitmapImage> image) { | 61 RefPtr<StaticBitmapImage> image) { |
68 std::unique_ptr<cc::SharedBitmap> bitmap = | 62 std::unique_ptr<cc::SharedBitmap> bitmap = |
69 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); | 63 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); |
70 if (!bitmap) | 64 if (!bitmap) |
71 return; | 65 return; |
72 unsigned char* pixels = bitmap->pixels(); | 66 unsigned char* pixels = bitmap->pixels(); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 } | 358 } |
365 break; | 359 break; |
366 case OffscreenCanvasCommitTypeCount: | 360 case OffscreenCanvasCommitTypeCount: |
367 NOTREACHED(); | 361 NOTREACHED(); |
368 } | 362 } |
369 | 363 |
370 if (m_changeSizeForNextCommit) { | 364 if (m_changeSizeForNextCommit) { |
371 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); | 365 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); |
372 m_changeSizeForNextCommit = false; | 366 m_changeSizeForNextCommit = false; |
373 } | 367 } |
368 | |
374 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame)); | 369 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame)); |
375 | |
376 // TODO(crbug.com/674744): Get BeginFrame to fire on its own. | |
377 scheduleSyntheticBeginFrame(); | |
378 } | |
379 | |
380 void OffscreenCanvasFrameDispatcherImpl::scheduleSyntheticBeginFrame() { | |
381 m_syntheticBeginFrameTask = | |
382 Platform::current() | |
383 ->currentThread() | |
384 ->getWebTaskRunner() | |
385 ->postDelayedCancellableTask( | |
386 BLINK_FROM_HERE, | |
387 WTF::bind(&OffscreenCanvasFrameDispatcherImpl::OnBeginFrame, | |
388 WTF::unretained(this), cc::BeginFrameArgs()), | |
389 16); | |
390 } | 370 } |
391 | 371 |
392 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { | 372 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { |
393 // TODO(fsamuel): Implement this. | 373 // TODO(fsamuel): Implement this. |
394 } | 374 } |
395 | 375 |
396 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( | 376 void OffscreenCanvasFrameDispatcherImpl::setNeedsBeginFrame( |
397 const cc::BeginFrameArgs& beginFrameArgs) { | 377 bool doesNeedBeginFrame) { |
Justin Novosad
2017/01/19 18:06:49
This name doesNeedBeginFrame is a bit awkward. Jus
xlai (Olivia)
2017/01/19 19:14:34
Done.
| |
398 if (!client()) | 378 if (doesNeedBeginFrame != m_needsBeginFrame) { |
399 return; | 379 m_needsBeginFrame = doesNeedBeginFrame; |
400 unsigned framesInFlight = m_cachedImages.size() + m_sharedBitmaps.size() + | 380 m_sink->SetNeedsBeginFrame(doesNeedBeginFrame); |
401 m_cachedTextureIds.size(); | |
402 | |
403 // Limit the rate of compositor commits. | |
404 if (framesInFlight < kMaximumOffscreenCanvasBufferCount) { | |
405 client()->beginFrame(); | |
406 } else { | |
407 // TODO(crbug.com/674744): Get BeginFrame to fire on its own. | |
408 // The following call is to reschedule the frame in cases where we encounter | |
409 // a backlog. | |
410 scheduleSyntheticBeginFrame(); | |
411 } | 381 } |
412 } | 382 } |
413 | 383 |
384 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( | |
385 const cc::BeginFrameArgs& beginFrameArgs) { | |
386 if (client()) | |
387 client()->beginFrame(); | |
388 } | |
389 | |
414 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( | 390 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( |
415 const cc::ReturnedResourceArray& resources) { | 391 const cc::ReturnedResourceArray& resources) { |
416 for (const auto& resource : resources) { | 392 for (const auto& resource : resources) { |
417 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); | 393 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); |
418 if (image) | 394 if (image) |
419 image->updateSyncToken(resource.sync_token); | 395 image->updateSyncToken(resource.sync_token); |
420 reclaimResource(resource.id); | 396 reclaimResource(resource.id); |
421 } | 397 } |
422 } | 398 } |
423 | 399 |
(...skipping 26 matching lines...) Expand all Loading... | |
450 | 426 |
451 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) { | 427 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) { |
452 if (m_width != width || m_height != height) { | 428 if (m_width != width || m_height != height) { |
453 m_width = width; | 429 m_width = width; |
454 m_height = height; | 430 m_height = height; |
455 m_changeSizeForNextCommit = true; | 431 m_changeSizeForNextCommit = true; |
456 } | 432 } |
457 } | 433 } |
458 | 434 |
459 } // namespace blink | 435 } // namespace blink |
OLD | NEW |