diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc deleted file mode 100644 index 4772ef9271a..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h" - -#include <memory> -#include "base/single_thread_task_runner.h" -#include "components/viz/common/quads/compositor_frame.h" -#include "components/viz/common/quads/texture_draw_quad.h" -#include "components/viz/common/resources/resource_format.h" -#include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" -#include "third_party/blink/renderer/platform/cross_thread_functional.h" -#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" -#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h" -#include "third_party/blink/renderer/platform/histogram.h" -#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/web_task_runner.h" - -namespace blink { - -enum { - kMaxPendingCompositorFrames = 2, - kMaxUnreclaimedPlaceholderFrames = 3, -}; - -OffscreenCanvasFrameDispatcher::OffscreenCanvasFrameDispatcher( - OffscreenCanvasFrameDispatcherClient* client, - uint32_t client_id, - uint32_t sink_id, - int canvas_id, - const IntSize& size) - : frame_sink_id_(viz::FrameSinkId(client_id, sink_id)), - size_(size), - change_size_for_next_commit_(false), - needs_begin_frame_(false), - binding_(this), - placeholder_canvas_id_(canvas_id), - num_unreclaimed_frames_posted_(0), - client_(client), - weak_ptr_factory_(this) { - if (frame_sink_id_.is_valid()) { - // Only frameless canvas pass an invalid frame sink id; we don't create - // mojo channel for this special case. - DCHECK(!sink_.is_bound()); - mojom::blink::EmbeddedFrameSinkProviderPtr provider; - Platform::Current()->GetInterfaceProvider()->GetInterface( - mojo::MakeRequest(&provider)); - DCHECK(provider); - - binding_.Bind(mojo::MakeRequest(&client_ptr_)); - provider->CreateCompositorFrameSink(frame_sink_id_, std::move(client_ptr_), - mojo::MakeRequest(&sink_)); - } - offscreen_canvas_resource_provider_ = - std::make_unique<OffscreenCanvasResourceProvider>(size_.Width(), - size_.Height(), this); -} - -OffscreenCanvasFrameDispatcher::~OffscreenCanvasFrameDispatcher() = default; - -namespace { - -void UpdatePlaceholderImage( - base::WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - int placeholder_canvas_id, - scoped_refptr<blink::StaticBitmapImage> image, - viz::ResourceId resource_id) { - DCHECK(IsMainThread()); - OffscreenCanvasPlaceholder* placeholder_canvas = - OffscreenCanvasPlaceholder::GetPlaceholderById(placeholder_canvas_id); - if (placeholder_canvas) { - placeholder_canvas->SetPlaceholderFrame( - std::move(image), std::move(dispatcher), std::move(task_runner), - resource_id); - } -} - -} // namespace - -void OffscreenCanvasFrameDispatcher::PostImageToPlaceholderIfNotBlocked( - scoped_refptr<StaticBitmapImage> image, - viz::ResourceId resource_id) { - if (placeholder_canvas_id_ == kInvalidPlaceholderCanvasId) { - offscreen_canvas_resource_provider_->ReclaimResource(resource_id); - return; - } - // Determines whether the main thread may be blocked. If unblocked, post the - // image. Otherwise, save the image and do not post it. - if (num_unreclaimed_frames_posted_ < kMaxUnreclaimedPlaceholderFrames) { - // After this point, |image| can only be used on the main thread, until it - // is returned. - image->Transfer(); - this->PostImageToPlaceholder(std::move(image), resource_id); - num_unreclaimed_frames_posted_++; - } else { - DCHECK(num_unreclaimed_frames_posted_ == kMaxUnreclaimedPlaceholderFrames); - if (latest_unposted_image_) { - // The previous unposted image becomes obsolete now. - offscreen_canvas_resource_provider_->ReclaimResource( - latest_unposted_resource_id_); - } - - latest_unposted_image_ = std::move(image); - latest_unposted_resource_id_ = resource_id; - } -} - -void OffscreenCanvasFrameDispatcher::PostImageToPlaceholder( - scoped_refptr<StaticBitmapImage> image, - viz::ResourceId resource_id) { - scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner = - Platform::Current()->CurrentThread()->GetTaskRunner(); - - PostCrossThreadTask( - *Platform::Current()->MainThread()->Scheduler()->CompositorTaskRunner(), - FROM_HERE, - CrossThreadBind(UpdatePlaceholderImage, this->GetWeakPtr(), - WTF::Passed(std::move(dispatcher_task_runner)), - placeholder_canvas_id_, std::move(image), resource_id)); -} - -void OffscreenCanvasFrameDispatcher::DispatchFrameSync( - scoped_refptr<StaticBitmapImage> image, - double commit_start_time, - const SkIRect& damage_rect) { - viz::CompositorFrame frame; - if (!PrepareFrame(std::move(image), commit_start_time, damage_rect, &frame)) - return; - - pending_compositor_frames_++; - WTF::Vector<viz::ReturnedResource> resources; - sink_->SubmitCompositorFrameSync( - parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(), - std::move(frame), nullptr, 0, &resources); - DidReceiveCompositorFrameAck(resources); -} - -void OffscreenCanvasFrameDispatcher::DispatchFrame( - scoped_refptr<StaticBitmapImage> image, - double commit_start_time, - const SkIRect& damage_rect) { - viz::CompositorFrame frame; - if (!PrepareFrame(std::move(image), commit_start_time, damage_rect, &frame)) - return; - - pending_compositor_frames_++; - sink_->SubmitCompositorFrame( - parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(), - std::move(frame), nullptr, 0); -} - -bool OffscreenCanvasFrameDispatcher::PrepareFrame( - scoped_refptr<StaticBitmapImage> image, - double commit_start_time, - const SkIRect& damage_rect, - viz::CompositorFrame* frame) { - if (!image || !VerifyImageSize(image->Size())) - return false; - - offscreen_canvas_resource_provider_->IncNextResourceId(); - - // For frameless canvas, we don't get a valid frame_sink_id and should drop. - if (!frame_sink_id_.is_valid()) { - PostImageToPlaceholderIfNotBlocked( - std::move(image), - offscreen_canvas_resource_provider_->GetNextResourceId()); - return false; - } - - // TODO(crbug.com/652931): update the device_scale_factor - frame->metadata.device_scale_factor = 1.0f; - if (current_begin_frame_ack_.sequence_number == - viz::BeginFrameArgs::kInvalidFrameNumber) { - // TODO(eseckler): This shouldn't be necessary when OffscreenCanvas no - // longer submits CompositorFrames without prior BeginFrame. - current_begin_frame_ack_ = viz::BeginFrameAck::CreateManualAckWithDamage(); - } else { - current_begin_frame_ack_.has_damage = true; - } - frame->metadata.begin_frame_ack = current_begin_frame_ack_; - - const gfx::Rect bounds(size_.Width(), size_.Height()); - const int kRenderPassId = 1; - bool is_clipped = false; - // TODO(crbug.com/705019): optimize for contexts that have {alpha: false} - bool are_contents_opaque = false; - std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create(); - pass->SetNew(kRenderPassId, bounds, - gfx::Rect(damage_rect.x(), damage_rect.y(), damage_rect.width(), - damage_rect.height()), - gfx::Transform()); - - viz::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); - sqs->SetAll(gfx::Transform(), bounds, bounds, bounds, is_clipped, - are_contents_opaque, 1.f, SkBlendMode::kSrcOver, 0); - - viz::TransferableResource resource; - offscreen_canvas_resource_provider_->TransferResource(&resource); - - bool yflipped = false; - OffscreenCanvasCommitType commit_type; - DEFINE_THREAD_SAFE_STATIC_LOCAL( - EnumerationHistogram, commit_type_histogram, - ("OffscreenCanvas.CommitType", kOffscreenCanvasCommitTypeCount)); - if (image->IsTextureBacked()) { - // While |image| is texture backed, it could be generated with "software - // rendering" aka swiftshader. If the compositor is not also using - // swiftshader, then we could not give a swiftshader based texture - // to the compositor. However in that case, IsGpuCompositingEnabled() will - // also be false, so we will avoid doing so. - if (SharedGpuContext::IsGpuCompositingEnabled()) { - // Case 1: both canvas and compositor are gpu accelerated. - commit_type = kCommitGPUCanvasGPUCompositing; - offscreen_canvas_resource_provider_ - ->SetTransferableResourceToStaticBitmapImage(resource, image); - yflipped = true; - } else { - // Case 2: canvas is accelerated but gpu compositing is disabled. - commit_type = kCommitGPUCanvasSoftwareCompositing; - offscreen_canvas_resource_provider_ - ->SetTransferableResourceToSharedBitmap(resource, image); - } - } else { - if (SharedGpuContext::IsGpuCompositingEnabled()) { - // Case 3: canvas is not gpu-accelerated, but compositor is. - commit_type = kCommitSoftwareCanvasGPUCompositing; - scoped_refptr<StaticBitmapImage> accelerated_image = - image->MakeAccelerated(SharedGpuContext::ContextProviderWrapper()); - if (!accelerated_image) - return false; - offscreen_canvas_resource_provider_ - ->SetTransferableResourceToStaticBitmapImage(resource, - accelerated_image); - } else { - // Case 4: both canvas and compositor are not gpu accelerated. - commit_type = kCommitSoftwareCanvasSoftwareCompositing; - offscreen_canvas_resource_provider_ - ->SetTransferableResourceToSharedBitmap(resource, image); - } - } - - commit_type_histogram.Count(commit_type); - - PostImageToPlaceholderIfNotBlocked( - std::move(image), - offscreen_canvas_resource_provider_->GetNextResourceId()); - - frame->resource_list.push_back(std::move(resource)); - - viz::TextureDrawQuad* quad = - pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>(); - gfx::Size rect_size(size_.Width(), size_.Height()); - - // TODO(crbug.com/705019): optimize for contexts that have {alpha: false} - const bool kNeedsBlending = true; - - // TODO(crbug.com/645993): this should be inherited from WebGL context's - // creation settings. - const bool kPremultipliedAlpha = true; - const gfx::PointF uv_top_left(0.f, 0.f); - const gfx::PointF uv_bottom_right(1.f, 1.f); - float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; - // TODO(crbug.com/645994): this should be true when using style - // "image-rendering: pixelated". - // TODO(crbug.com/645590): filter should respect the image-rendering CSS - // property of associated canvas element. - const bool kNearestNeighbor = false; - quad->SetAll(sqs, bounds, bounds, kNeedsBlending, resource.id, gfx::Size(), - kPremultipliedAlpha, uv_top_left, uv_bottom_right, - SK_ColorTRANSPARENT, vertex_opacity, yflipped, kNearestNeighbor, - false); - - frame->render_pass_list.push_back(std::move(pass)); - - double elapsed_time = WTF::CurrentTimeTicksInSeconds() - commit_start_time; - - switch (commit_type) { - case kCommitGPUCanvasGPUCompositing: - if (IsMainThread()) { - DEFINE_STATIC_LOCAL( - CustomCountHistogram, commit_gpu_canvas_gpu_compositing_main_timer, - ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingMain", 0, - 10000000, 50)); - commit_gpu_canvas_gpu_compositing_main_timer.Count(elapsed_time * - 1000000.0); - } else { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, - commit_gpu_canvas_gpu_compositing_worker_timer, - ("Blink.Canvas.OffscreenCommit.GPUCanvasGPUCompositingWorker", 0, - 10000000, 50)); - commit_gpu_canvas_gpu_compositing_worker_timer.Count(elapsed_time * - 1000000.0); - } - break; - case kCommitGPUCanvasSoftwareCompositing: - if (IsMainThread()) { - DEFINE_STATIC_LOCAL( - CustomCountHistogram, - commit_gpu_canvas_software_compositing_main_timer, - ("Blink.Canvas.OffscreenCommit.GPUCanvasSoftwareCompositingMain", 0, - 10000000, 50)); - commit_gpu_canvas_software_compositing_main_timer.Count(elapsed_time * - 1000000.0); - } else { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, - commit_gpu_canvas_software_compositing_worker_timer, - ("Blink.Canvas.OffscreenCommit." - "GPUCanvasSoftwareCompositingWorker", - 0, 10000000, 50)); - commit_gpu_canvas_software_compositing_worker_timer.Count(elapsed_time * - 1000000.0); - } - break; - case kCommitSoftwareCanvasGPUCompositing: - if (IsMainThread()) { - DEFINE_STATIC_LOCAL( - CustomCountHistogram, - commit_software_canvas_gpu_compositing_main_timer, - ("Blink.Canvas.OffscreenCommit.SoftwareCanvasGPUCompositingMain", 0, - 10000000, 50)); - commit_software_canvas_gpu_compositing_main_timer.Count(elapsed_time * - 1000000.0); - } else { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, - commit_software_canvas_gpu_compositing_worker_timer, - ("Blink.Canvas.OffscreenCommit." - "SoftwareCanvasGPUCompositingWorker", - 0, 10000000, 50)); - commit_software_canvas_gpu_compositing_worker_timer.Count(elapsed_time * - 1000000.0); - } - break; - case kCommitSoftwareCanvasSoftwareCompositing: - if (IsMainThread()) { - DEFINE_STATIC_LOCAL( - CustomCountHistogram, - commit_software_canvas_software_compositing_main_timer, - ("Blink.Canvas.OffscreenCommit." - "SoftwareCanvasSoftwareCompositingMain", - 0, 10000000, 50)); - commit_software_canvas_software_compositing_main_timer.Count( - elapsed_time * 1000000.0); - } else { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, - commit_software_canvas_software_compositing_worker_timer, - ("Blink.Canvas.OffscreenCommit." - "SoftwareCanvasSoftwareCompositingWorker", - 0, 10000000, 50)); - commit_software_canvas_software_compositing_worker_timer.Count( - elapsed_time * 1000000.0); - } - break; - case kOffscreenCanvasCommitTypeCount: - NOTREACHED(); - } - - if (change_size_for_next_commit_) { - parent_local_surface_id_allocator_.GenerateId(); - change_size_for_next_commit_ = false; - } - - return true; -} - -void OffscreenCanvasFrameDispatcher::DidReceiveCompositorFrameAck( - const WTF::Vector<viz::ReturnedResource>& resources) { - ReclaimResources(resources); - pending_compositor_frames_--; - DCHECK_GE(pending_compositor_frames_, 0); -} - -void OffscreenCanvasFrameDispatcher::DidPresentCompositorFrame( - uint32_t presentation_token, - mojo_base::mojom::blink::TimeTicksPtr time, - WTF::TimeDelta refresh, - uint32_t flags) { - NOTIMPLEMENTED(); -} - -void OffscreenCanvasFrameDispatcher::DidDiscardCompositorFrame( - uint32_t presentation_token) { - NOTIMPLEMENTED(); -} - -void OffscreenCanvasFrameDispatcher::SetNeedsBeginFrame( - bool needs_begin_frame) { - if (needs_begin_frame_ == needs_begin_frame) - return; - needs_begin_frame_ = needs_begin_frame; - if (!suspend_animation_) - SetNeedsBeginFrameInternal(); -} - -void OffscreenCanvasFrameDispatcher::SetSuspendAnimation( - bool suspend_animation) { - if (suspend_animation_ == suspend_animation) - return; - suspend_animation_ = suspend_animation; - if (needs_begin_frame_) - SetNeedsBeginFrameInternal(); -} - -void OffscreenCanvasFrameDispatcher::SetNeedsBeginFrameInternal() { - if (sink_) { - sink_->SetNeedsBeginFrame(needs_begin_frame_ && !suspend_animation_); - } -} - -void OffscreenCanvasFrameDispatcher::OnBeginFrame( - const viz::BeginFrameArgs& begin_frame_args) { - DCHECK(Client()); - - current_begin_frame_ack_ = viz::BeginFrameAck( - begin_frame_args.source_id, begin_frame_args.sequence_number, false); - if (pending_compositor_frames_ >= kMaxPendingCompositorFrames || - (begin_frame_args.type == viz::BeginFrameArgs::MISSED && - base::TimeTicks::Now() > begin_frame_args.deadline)) { - sink_->DidNotProduceFrame(current_begin_frame_ack_); - return; - } - - Client()->BeginFrame(); - // TODO(eseckler): Tell |m_sink| if we did not draw during the BeginFrame. - current_begin_frame_ack_.sequence_number = - viz::BeginFrameArgs::kInvalidFrameNumber; -} - -void OffscreenCanvasFrameDispatcher::ReclaimResources( - const WTF::Vector<viz::ReturnedResource>& resources) { - offscreen_canvas_resource_provider_->ReclaimResources(resources); -} - -void OffscreenCanvasFrameDispatcher::ReclaimResource( - viz::ResourceId resource_id) { - offscreen_canvas_resource_provider_->ReclaimResource(resource_id); - num_unreclaimed_frames_posted_--; - - // The main thread has become unblocked recently and we have an image that - // have not been posted yet. - if (latest_unposted_image_) { - DCHECK(num_unreclaimed_frames_posted_ == - kMaxUnreclaimedPlaceholderFrames - 1); - PostImageToPlaceholderIfNotBlocked(std::move(latest_unposted_image_), - latest_unposted_resource_id_); - latest_unposted_resource_id_ = 0; - } -} - -bool OffscreenCanvasFrameDispatcher::VerifyImageSize(const IntSize image_size) { - if (image_size == size_) - return true; - return false; -} - -void OffscreenCanvasFrameDispatcher::Reshape(const IntSize& size) { - if (size_ != size) { - size_ = size; - offscreen_canvas_resource_provider_->Reshape(size_.Width(), size_.Height()); - change_size_for_next_commit_ = true; - } -} - -void OffscreenCanvasFrameDispatcher::DidAllocateSharedBitmap( - mojo::ScopedSharedBufferHandle buffer, - ::gpu::mojom::blink::MailboxPtr id) { - sink_->DidAllocateSharedBitmap(std::move(buffer), std::move(id)); -} - -void OffscreenCanvasFrameDispatcher::DidDeleteSharedBitmap( - ::gpu::mojom::blink::MailboxPtr id) { - sink_->DidDeleteSharedBitmap(std::move(id)); -} - -} // namespace blink |