Chromium Code Reviews| 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" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 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 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( | 30 OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( |
| 31 OffscreenCanvasFrameDispatcherClient* client, | |
| 31 uint32_t clientId, | 32 uint32_t clientId, |
| 32 uint32_t sinkId, | 33 uint32_t sinkId, |
| 33 int canvasId, | 34 int canvasId, |
| 34 int width, | 35 int width, |
| 35 int height) | 36 int height) |
| 36 : m_frameSinkId(cc::FrameSinkId(clientId, sinkId)), | 37 : OffscreenCanvasFrameDispatcher(client), |
| 38 m_frameSinkId(cc::FrameSinkId(clientId, sinkId)), | |
| 37 m_width(width), | 39 m_width(width), |
| 38 m_height(height), | 40 m_height(height), |
| 39 m_nextResourceId(1u), | 41 m_nextResourceId(1u), |
| 40 m_binding(this), | 42 m_binding(this), |
| 41 m_placeholderCanvasId(canvasId) { | 43 m_placeholderCanvasId(canvasId) { |
| 42 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); | 44 m_currentLocalFrameId = m_surfaceIdAllocator.GenerateId(); |
| 43 DCHECK(!m_sink.is_bound()); | 45 DCHECK(!m_sink.is_bound()); |
| 44 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; | 46 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; |
| 45 Platform::current()->interfaceProvider()->getInterface( | 47 Platform::current()->interfaceProvider()->getInterface( |
| 46 mojo::MakeRequest(&provider)); | 48 mojo::MakeRequest(&provider)); |
| 47 provider->CreateCompositorFrameSink(m_frameSinkId, | 49 provider->CreateCompositorFrameSink(m_frameSinkId, |
| 48 m_binding.CreateInterfacePtrAndBind(), | 50 m_binding.CreateInterfacePtrAndBind(), |
| 49 mojo::MakeRequest(&m_sink)); | 51 mojo::MakeRequest(&m_sink)); |
| 50 } | 52 } |
| 51 | 53 |
| 54 OffscreenCanvasFrameDispatcherImpl::~OffscreenCanvasFrameDispatcherImpl() { | |
| 55 m_syntheticBeginFrameTask.cancel(); | |
| 56 } | |
| 57 | |
| 52 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( | 58 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceToSharedBitmap( |
| 53 cc::TransferableResource& resource, | 59 cc::TransferableResource& resource, |
| 54 RefPtr<StaticBitmapImage> image) { | 60 RefPtr<StaticBitmapImage> image) { |
| 55 std::unique_ptr<cc::SharedBitmap> bitmap = | 61 std::unique_ptr<cc::SharedBitmap> bitmap = |
| 56 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); | 62 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); |
| 57 if (!bitmap) | 63 if (!bitmap) |
| 58 return; | 64 return; |
| 59 unsigned char* pixels = bitmap->pixels(); | 65 unsigned char* pixels = bitmap->pixels(); |
| 60 DCHECK(pixels); | 66 DCHECK(pixels); |
| 61 SkImageInfo imageInfo = SkImageInfo::Make( | 67 SkImageInfo imageInfo = SkImageInfo::Make( |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 } | 176 } |
| 171 } | 177 } |
| 172 | 178 |
| 173 } // namespace | 179 } // namespace |
| 174 | 180 |
| 175 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( | 181 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| 176 RefPtr<StaticBitmapImage> image, | 182 RefPtr<StaticBitmapImage> image, |
| 177 double commitStartTime, | 183 double commitStartTime, |
| 178 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is | 184 bool isWebGLSoftwareRendering /* This flag is true when WebGL's commit is |
| 179 called on SwiftShader. */) { | 185 called on SwiftShader. */) { |
| 180 if (!image) | 186 if (!image || !verifyImageSize(image->size())) |
| 181 return; | |
| 182 if (!verifyImageSize(image->size())) | |
| 183 return; | 187 return; |
| 184 cc::CompositorFrame frame; | 188 cc::CompositorFrame frame; |
| 185 // TODO(crbug.com/652931): update the device_scale_factor | 189 // TODO(crbug.com/652931): update the device_scale_factor |
| 186 frame.metadata.device_scale_factor = 1.0f; | 190 frame.metadata.device_scale_factor = 1.0f; |
| 187 | 191 |
| 188 const gfx::Rect bounds(m_width, m_height); | 192 const gfx::Rect bounds(m_width, m_height); |
| 189 const int renderPassId = 1; | 193 const int renderPassId = 1; |
| 190 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); | 194 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); |
| 191 pass->SetNew(renderPassId, bounds, bounds, gfx::Transform()); | 195 pass->SetNew(renderPassId, bounds, bounds, gfx::Transform()); |
| 192 pass->has_transparent_background = false; | 196 pass->has_transparent_background = false; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 0, 10000000, 50)); | 355 0, 10000000, 50)); |
| 352 commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * | 356 commitSoftwareCanvasSoftwareCompositingWorkerTimer.count(elapsedTime * |
| 353 1000000.0); | 357 1000000.0); |
| 354 } | 358 } |
| 355 break; | 359 break; |
| 356 case OffscreenCanvasCommitTypeCount: | 360 case OffscreenCanvasCommitTypeCount: |
| 357 NOTREACHED(); | 361 NOTREACHED(); |
| 358 } | 362 } |
| 359 | 363 |
| 360 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame)); | 364 m_sink->SubmitCompositorFrame(m_currentLocalFrameId, std::move(frame)); |
| 365 | |
| 366 // TODO(crbug.com/674744): Get BeginFrame to fire on its own. | |
| 367 scheduleSyntheticBeginFrame(); | |
| 368 } | |
| 369 | |
| 370 void OffscreenCanvasFrameDispatcherImpl::scheduleSyntheticBeginFrame() { | |
| 371 m_syntheticBeginFrameTask = | |
| 372 Platform::current() | |
| 373 ->currentThread() | |
| 374 ->getWebTaskRunner() | |
| 375 ->postDelayedCancellableTask( | |
| 376 BLINK_FROM_HERE, | |
| 377 WTF::bind(&OffscreenCanvasFrameDispatcherImpl::OnBeginFrame, | |
| 378 WTF::unretained(this), cc::BeginFrameArgs()), | |
| 379 16); | |
| 361 } | 380 } |
| 362 | 381 |
| 363 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { | 382 void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck() { |
| 364 // TODO(fsamuel): Implement this. | 383 // TODO(fsamuel): Implement this. |
| 365 } | 384 } |
| 366 | 385 |
| 367 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( | 386 void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( |
| 368 const cc::BeginFrameArgs& beginFrameArgs) {} | 387 const cc::BeginFrameArgs& beginFrameArgs) { |
| 388 if (!client()) | |
| 389 return; | |
| 390 unsigned framesInFlight = m_cachedImages.size() + m_sharedBitmaps.size() + | |
| 391 m_cachedTextureIds.size(); | |
| 392 if (framesInFlight < 3) { // Backpressure guard | |
|
Stephen White
2016/12/21 15:14:43
Make this be a compile-time constant?
| |
| 393 client()->beginFrame(); | |
| 394 } else { | |
| 395 // TODO(crbug.com/674744): Get BeginFrame to fire on its own. | |
| 396 // The following call is to reschedule the frame in cases where we encounter | |
| 397 // a backlog. | |
| 398 scheduleSyntheticBeginFrame(); | |
| 399 } | |
| 400 } | |
| 369 | 401 |
| 370 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( | 402 void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( |
| 371 const cc::ReturnedResourceArray& resources) { | 403 const cc::ReturnedResourceArray& resources) { |
| 372 for (const auto& resource : resources) { | 404 for (const auto& resource : resources) { |
| 373 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); | 405 RefPtr<StaticBitmapImage> image = m_cachedImages.get(resource.id); |
| 374 if (image) | 406 if (image) |
| 375 image->updateSyncToken(resource.sync_token); | 407 image->updateSyncToken(resource.sync_token); |
| 376 reclaimResource(resource.id); | 408 reclaimResource(resource.id); |
| 377 } | 409 } |
| 378 } | 410 } |
| 379 | 411 |
| 380 void OffscreenCanvasFrameDispatcherImpl::WillDrawSurface() { | 412 void OffscreenCanvasFrameDispatcherImpl::WillDrawSurface() { |
| 381 // TODO(fsamuel, staraz): Implement this. | 413 // TODO(fsamuel, staraz): Implement this. |
| 382 NOTIMPLEMENTED(); | |
| 383 } | 414 } |
| 384 | 415 |
| 385 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) { | 416 void OffscreenCanvasFrameDispatcherImpl::reclaimResource(unsigned resourceId) { |
| 386 // An image resource needs to be returned by both the | 417 // An image resource needs to be returned by both the |
| 387 // CompositorFrameSink and the HTMLCanvasElement. These | 418 // CompositorFrameSink and the HTMLCanvasElement. These |
| 388 // events can happen in any order. The first of the two | 419 // events can happen in any order. The first of the two |
| 389 // to return a given resource will result in the spare | 420 // to return a given resource will result in the spare |
| 390 // resource lock being lifted, and the second will delete | 421 // resource lock being lifted, and the second will delete |
| 391 // the resource for real. | 422 // the resource for real. |
| 392 if (m_spareResourceLocks.contains(resourceId)) { | 423 if (m_spareResourceLocks.contains(resourceId)) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 404 return true; | 435 return true; |
| 405 return false; | 436 return false; |
| 406 } | 437 } |
| 407 | 438 |
| 408 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) { | 439 void OffscreenCanvasFrameDispatcherImpl::reshape(int width, int height) { |
| 409 m_width = width; | 440 m_width = width; |
| 410 m_height = height; | 441 m_height = height; |
| 411 } | 442 } |
| 412 | 443 |
| 413 } // namespace blink | 444 } // namespace blink |
| OLD | NEW |