Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp |
| index 970e6a6f35b3090e2c69ff0de021474c53bf8a36..86f8611d7b0b27c0fc11a7f456699b2de269a839 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp |
| @@ -7,7 +7,10 @@ |
| #include "cc/output/compositor_frame.h" |
| #include "cc/quads/texture_draw_quad.h" |
| #include "gpu/command_buffer/client/gles2_interface.h" |
| +#include "platform/CrossThreadFunctional.h" |
| #include "platform/Histogram.h" |
| +#include "platform/WebTaskRunner.h" |
| +#include "platform/graphics/OffscreenCanvasPlaceholder.h" |
| #include "platform/graphics/gpu/SharedGpuContext.h" |
| #include "public/platform/InterfaceProvider.h" |
| #include "public/platform/Platform.h" |
| @@ -29,6 +32,7 @@ OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( |
| uint32_t sinkId, |
| uint32_t localId, |
| uint64_t nonce, |
| + int canvasId, |
| int width, |
| int height) |
| : m_surfaceId(cc::FrameSinkId(clientId, sinkId), |
| @@ -36,7 +40,8 @@ OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( |
| m_width(width), |
| m_height(height), |
| m_nextResourceId(1u), |
| - m_binding(this) { |
| + m_binding(this), |
| + m_placeholderCanvasId(canvasId) { |
| DCHECK(!m_sink.is_bound()); |
| mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; |
| Platform::current()->interfaceProvider()->getInterface( |
| @@ -146,6 +151,25 @@ void OffscreenCanvasFrameDispatcherImpl:: |
| m_cachedImages.add(m_nextResourceId, std::move(image)); |
| } |
| +namespace { |
| + |
| +void updatePlaceholderImage(WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher, |
| + std::unique_ptr<WebTaskRunner> taskRunner, |
| + int placeholderCanvasId, |
| + RefPtr<blink::Image> image, |
| + unsigned resourceId) { |
| + DCHECK(isMainThread()); |
| + OffscreenCanvasPlaceholder* placeholderCanvas = |
| + OffscreenCanvasPlaceholder::getPlaceholderById(placeholderCanvasId); |
| + if (placeholderCanvas) { |
| + placeholderCanvas->setPlaceholderFrame(std::move(image), |
| + std::move(dispatcher), |
| + std::move(taskRunner), resourceId); |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| RefPtr<StaticBitmapImage> image, |
| double commitStartTime, |
| @@ -211,6 +235,20 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| setTransferableResourceToSharedBitmap(resource, image); |
| } |
| } |
| + |
| + // After this point, |image| can only be used on the main thread, until |
| + // it is returned. |
| + image->transfer(); |
|
xlai (Olivia)
2016/11/11 16:28:33
In the case of gpu-accelerated offscreencanvas, th
Justin Novosad
2016/11/11 22:09:00
The idea is that We don't need to use this snapsho
|
| + std::unique_ptr<WebTaskRunner> dispatcherTaskRunner = |
| + Platform::current()->currentThread()->getWebTaskRunner()->clone(); |
| + |
| + Platform::current()->mainThread()->getWebTaskRunner()->postTask( |
|
xlai (Olivia)
2016/11/11 16:28:33
This dispatchFrame() is invoked in every commit().
Justin Novosad
2016/11/11 22:09:00
I tried that and it is actually more complicated w
|
| + BLINK_FROM_HERE, |
| + crossThreadBind(updatePlaceholderImage, this->createWeakPtr(), |
| + passed(std::move(dispatcherTaskRunner)), |
| + m_placeholderCanvasId, std::move(image), resource.id)); |
| + m_spareResourceLocks.add(m_nextResourceId); |
| + |
| commitTypeHistogram.count(commitType); |
| m_nextResourceId++; |
| @@ -238,6 +276,10 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| frame.render_pass_list.push_back(std::move(pass)); |
| double elapsedTime = WTF::monotonicallyIncreasingTime() - commitStartTime; |
| + |
| + // TODO(crbug.com/663916): The off-main-thread metrics are commented-out |
| + // because they cause thread check errors (static variable accessed in many |
| + // threads) |
| switch (commitType) { |
| case CommitGPUCanvasGPUCompositing: |
| if (isMainThread()) { |
| @@ -246,13 +288,13 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingMain", 0, |
| 10000000, 50)); |
| commitGPUCanvasGPUCompositingMainTimer.count(elapsedTime * 1000000.0); |
| - } else { |
| + } /* else { |
| DEFINE_STATIC_LOCAL( |
| CustomCountHistogram, commitGPUCanvasGPUCompositingWorkerTimer, |
| ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingWorker", 0, |
| 10000000, 50)); |
| commitGPUCanvasGPUCompositingWorkerTimer.count(elapsedTime * 1000000.0); |
| - } |
| + } */ |
| break; |
| case CommitGPUCanvasSoftwareCompositing: |
| if (isMainThread()) { |
| @@ -262,14 +304,14 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| 10000000, 50)); |
| commitGPUCanvasSoftwareCompositingMainTimer.count(elapsedTime * |
| 1000000.0); |
| - } else { |
| + } /* else { |
| DEFINE_STATIC_LOCAL( |
| CustomCountHistogram, commitGPUCanvasSoftwareCompositingWorkerTimer, |
| ("Blink.Canvas.OffscreenCommit.GPUCanvasSoftwareCompositingWorker", |
| 0, 10000000, 50)); |
| commitGPUCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * |
| 1000000.0); |
| - } |
| + } */ |
| break; |
| case CommitSoftwareCanvasGPUCompositing: |
| if (isMainThread()) { |
| @@ -279,14 +321,14 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| 10000000, 50)); |
| commitSoftwareCanvasGPUCompositingMainTimer.count(elapsedTime * |
| 1000000.0); |
| - } else { |
| + } /* else { |
| DEFINE_STATIC_LOCAL( |
| CustomCountHistogram, commitSoftwareCanvasGPUCompositingWorkerTimer, |
| ("Blink.Canvas.OffscreenCommit.SoftwareCanvasGPUCompositingWorker", |
| 0, 10000000, 50)); |
| commitSoftwareCanvasGPUCompositingWorkerTimer.count(elapsedTime * |
| 1000000.0); |
| - } |
| + } */ |
| break; |
| case CommitSoftwareCanvasSoftwareCompositing: |
| if (isMainThread()) { |
| @@ -297,7 +339,7 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| 0, 10000000, 50)); |
| commitSoftwareCanvasSoftwareCompositingMainTimer.count(elapsedTime * |
| 1000000.0); |
| - } else { |
| + } /* else { |
| DEFINE_STATIC_LOCAL(CustomCountHistogram, |
| commitSoftwareCanvasSoftwareCompositingWorkerTimer, |
| ("Blink.Canvas.OffscreenCommit." |
| @@ -305,7 +347,7 @@ void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| 0, 10000000, 50)); |
| commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * |
| 1000000.0); |
| - } |
| + } */ |
| break; |
| case OffscreenCanvasCommitTypeCount: |
| NOTREACHED(); |
| @@ -327,10 +369,24 @@ void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( |
| RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); |
| if (image) |
| image->updateSyncToken(resource.sync_token); |
| - m_cachedImages.remove(resource.id); |
| - m_sharedBitmaps.remove(resource.id); |
| - m_cachedTextureIds.remove(resource.id); |
| + reclaimResource(resource.id); |
| + } |
| +} |
| + |
| +void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) { |
| + // An image resource needs to be returned by both the |
| + // CompositorFrameSink and the HTMLCanvasElement. These |
| + // events can happen in any order. The first of the two |
| + // to return a given resource will result in the spare |
| + // resource lock being lifted, and the second will delete |
| + // the resource for real. |
| + if (m_spareResourceLocks.contains(resourceId)) { |
| + m_spareResourceLocks.remove(resourceId); |
| + return; |
| } |
| + m_cachedImages.remove(resourceId); |
| + m_sharedBitmaps.remove(resourceId); |
| + m_cachedTextureIds.remove(resourceId); |
| } |
| bool OffscreenCanvasFrameDispatcherImpl::verifyImageSize( |