Index: content/renderer/android/synchronous_compositor_output_surface.cc |
diff --git a/content/renderer/android/synchronous_compositor_output_surface.cc b/content/renderer/android/synchronous_compositor_output_surface.cc |
deleted file mode 100644 |
index c6289fee9c0053e8498c2ae04e0737d5188f0d34..0000000000000000000000000000000000000000 |
--- a/content/renderer/android/synchronous_compositor_output_surface.cc |
+++ /dev/null |
@@ -1,435 +0,0 @@ |
-// Copyright 2013 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 "content/renderer/android/synchronous_compositor_output_surface.h" |
- |
-#include <vector> |
- |
-#include "base/auto_reset.h" |
-#include "base/location.h" |
-#include "base/logging.h" |
-#include "base/macros.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/single_thread_task_runner.h" |
-#include "base/threading/thread_task_runner_handle.h" |
-#include "cc/output/compositor_frame.h" |
-#include "cc/output/context_provider.h" |
-#include "cc/output/output_surface_client.h" |
-#include "cc/output/renderer_settings.h" |
-#include "cc/output/software_output_device.h" |
-#include "cc/output/texture_mailbox_deleter.h" |
-#include "cc/surfaces/display.h" |
-#include "cc/surfaces/surface_factory.h" |
-#include "cc/surfaces/surface_id_allocator.h" |
-#include "cc/surfaces/surface_manager.h" |
-#include "content/common/android/sync_compositor_messages.h" |
-#include "content/renderer/android/synchronous_compositor_filter.h" |
-#include "content/renderer/android/synchronous_compositor_registry.h" |
-#include "content/renderer/gpu/frame_swap_message_queue.h" |
-#include "content/renderer/render_thread_impl.h" |
-#include "gpu/command_buffer/client/context_support.h" |
-#include "gpu/command_buffer/client/gles2_interface.h" |
-#include "gpu/command_buffer/common/gpu_memory_allocation.h" |
-#include "ipc/ipc_message.h" |
-#include "ipc/ipc_message_macros.h" |
-#include "ipc/ipc_sender.h" |
-#include "third_party/skia/include/core/SkCanvas.h" |
-#include "ui/gfx/geometry/rect_conversions.h" |
-#include "ui/gfx/skia_util.h" |
-#include "ui/gfx/transform.h" |
- |
-namespace content { |
- |
-namespace { |
- |
-const int64_t kFallbackTickTimeoutInMilliseconds = 100; |
-const uint32_t kCompositorClientId = 1; |
- |
-// Do not limit number of resources, so use an unrealistically high value. |
-const size_t kNumResourcesLimit = 10 * 1000 * 1000; |
- |
-class SoftwareDevice : public cc::SoftwareOutputDevice { |
- public: |
- SoftwareDevice(SkCanvas** canvas) : canvas_(canvas) {} |
- |
- void Resize(const gfx::Size& pixel_size, float scale_factor) override { |
- // Intentional no-op: canvas size is controlled by the embedder. |
- } |
- SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override { |
- DCHECK(*canvas_) << "BeginPaint with no canvas set"; |
- return *canvas_; |
- } |
- void EndPaint() override {} |
- |
- private: |
- SkCanvas** canvas_; |
- |
- DISALLOW_COPY_AND_ASSIGN(SoftwareDevice); |
-}; |
- |
-} // namespace |
- |
-class SynchronousCompositorOutputSurface::SoftwareOutputSurface |
- : public cc::OutputSurface { |
- public: |
- SoftwareOutputSurface(std::unique_ptr<SoftwareDevice> software_device) |
- : cc::OutputSurface(nullptr, nullptr, std::move(software_device)) {} |
- |
- // cc::OutputSurface implementation. |
- uint32_t GetFramebufferCopyTextureFormat() override { return 0; } |
- void SwapBuffers(cc::CompositorFrame frame) override {} |
- void Reshape(const gfx::Size& size, |
- float scale_factor, |
- const gfx::ColorSpace& color_space, |
- bool has_alpha) override { |
- // Intentional no-op. Surface size controlled by embedder. |
- } |
- |
- void SetSurfaceSize(const gfx::Size surface_size) { |
- surface_size_ = surface_size; |
- } |
-}; |
- |
-SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( |
- scoped_refptr<cc::ContextProvider> context_provider, |
- scoped_refptr<cc::ContextProvider> worker_context_provider, |
- int routing_id, |
- uint32_t output_surface_id, |
- std::unique_ptr<cc::BeginFrameSource> begin_frame_source, |
- SynchronousCompositorRegistry* registry, |
- scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue) |
- : cc::OutputSurface(std::move(context_provider), |
- std::move(worker_context_provider), |
- nullptr), |
- routing_id_(routing_id), |
- output_surface_id_(output_surface_id), |
- registry_(registry), |
- sender_(RenderThreadImpl::current()->sync_compositor_message_filter()), |
- memory_policy_(0u), |
- frame_swap_message_queue_(frame_swap_message_queue), |
- surface_manager_(new cc::SurfaceManager), |
- surface_id_allocator_(new cc::SurfaceIdAllocator(kCompositorClientId)), |
- surface_factory_(new cc::SurfaceFactory(surface_manager_.get(), this)), |
- begin_frame_source_(std::move(begin_frame_source)) { |
- DCHECK(registry_); |
- DCHECK(sender_); |
- DCHECK(begin_frame_source_); |
- thread_checker_.DetachFromThread(); |
- capabilities_.adjust_deadline_for_parent = false; |
- capabilities_.delegated_rendering = true; |
- memory_policy_.priority_cutoff_when_visible = |
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; |
-} |
- |
-SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() = |
- default; |
- |
-void SynchronousCompositorOutputSurface::SetSyncClient( |
- SynchronousCompositorOutputSurfaceClient* compositor) { |
- DCHECK(CalledOnValidThread()); |
- sync_client_ = compositor; |
- if (sync_client_) |
- Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_)); |
-} |
- |
-bool SynchronousCompositorOutputSurface::OnMessageReceived( |
- const IPC::Message& message) { |
- bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorOutputSurface, message) |
- IPC_MESSAGE_HANDLER(SyncCompositorMsg_SetMemoryPolicy, SetMemoryPolicy) |
- IPC_MESSAGE_HANDLER(SyncCompositorMsg_ReclaimResources, OnReclaimResources) |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP() |
- return handled; |
-} |
- |
-bool SynchronousCompositorOutputSurface::BindToClient( |
- cc::OutputSurfaceClient* surface_client) { |
- DCHECK(CalledOnValidThread()); |
- if (!cc::OutputSurface::BindToClient(surface_client)) |
- return false; |
- |
- DCHECK(begin_frame_source_); |
- client_->SetBeginFrameSource(begin_frame_source_.get()); |
- client_->SetMemoryPolicy(memory_policy_); |
- client_->SetTreeActivationCallback( |
- base::Bind(&SynchronousCompositorOutputSurface::DidActivatePendingTree, |
- base::Unretained(this))); |
- registry_->RegisterOutputSurface(routing_id_, this); |
- registered_ = true; |
- |
- surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id()); |
- surface_manager_->RegisterSurfaceFactoryClient( |
- surface_id_allocator_->client_id(), this); |
- |
- cc::RendererSettings software_renderer_settings; |
- |
- std::unique_ptr<SoftwareOutputSurface> output_surface( |
- new SoftwareOutputSurface( |
- base::MakeUnique<SoftwareDevice>(¤t_sw_canvas_))); |
- software_output_surface_ = output_surface.get(); |
- |
- // The shared_bitmap_manager and gpu_memory_buffer_manager here are null as |
- // this Display is only used for resourcesless software draws, where no |
- // resources are included in the frame swapped from the compositor. So there |
- // is no need for these. |
- display_.reset(new cc::Display( |
- nullptr /* shared_bitmap_manager */, |
- nullptr /* gpu_memory_buffer_manager */, software_renderer_settings, |
- nullptr /* begin_frame_source */, std::move(output_surface), |
- nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */)); |
- display_->Initialize(&display_client_, surface_manager_.get(), |
- surface_id_allocator_->client_id()); |
- display_->SetVisible(true); |
- return true; |
-} |
- |
-void SynchronousCompositorOutputSurface::DetachFromClient() { |
- DCHECK(CalledOnValidThread()); |
- client_->SetBeginFrameSource(nullptr); |
- // Destroy the begin frame source on the same thread it was bound on. |
- begin_frame_source_ = nullptr; |
- if (registered_) |
- registry_->UnregisterOutputSurface(routing_id_, this); |
- client_->SetTreeActivationCallback(base::Closure()); |
- if (!delegated_surface_id_.is_null()) |
- surface_factory_->Destroy(delegated_surface_id_); |
- surface_manager_->UnregisterSurfaceFactoryClient( |
- surface_id_allocator_->client_id()); |
- surface_manager_->InvalidateSurfaceClientId( |
- surface_id_allocator_->client_id()); |
- software_output_surface_ = nullptr; |
- display_ = nullptr; |
- surface_factory_ = nullptr; |
- surface_id_allocator_ = nullptr; |
- surface_manager_ = nullptr; |
- cc::OutputSurface::DetachFromClient(); |
- CancelFallbackTick(); |
-} |
- |
-void SynchronousCompositorOutputSurface::Reshape( |
- const gfx::Size& size, |
- float scale_factor, |
- const gfx::ColorSpace& color_space, |
- bool has_alpha) { |
- // Intentional no-op: surface size is controlled by the embedder. |
-} |
- |
-static void NoOpDrawCallback() {} |
- |
-void SynchronousCompositorOutputSurface::SwapBuffers( |
- cc::CompositorFrame frame) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(sync_client_); |
- |
- if (fallback_tick_running_) { |
- DCHECK(frame.delegated_frame_data->resource_list.empty()); |
- cc::ReturnedResourceArray return_resources; |
- ReturnResources(return_resources); |
- did_swap_ = true; |
- return; |
- } |
- |
- cc::CompositorFrame swap_frame; |
- |
- if (in_software_draw_) { |
- // The frame we send to the client is actually just the metadata. Preserve |
- // the |frame| for the software path below. |
- swap_frame.metadata = frame.metadata.Clone(); |
- |
- if (delegated_surface_id_.is_null()) { |
- delegated_surface_id_ = surface_id_allocator_->GenerateId(); |
- surface_factory_->Create(delegated_surface_id_); |
- } |
- |
- display_->SetSurfaceId(delegated_surface_id_, |
- frame.metadata.device_scale_factor); |
- |
- gfx::Size frame_size = |
- frame.delegated_frame_data->render_pass_list.back()->output_rect.size(); |
- display_->Resize(frame_size); |
- |
- surface_factory_->SubmitCompositorFrame( |
- delegated_surface_id_, std::move(frame), base::Bind(&NoOpDrawCallback)); |
- display_->DrawAndSwap(); |
- } else { |
- // For hardware draws we send the whole frame to the client so it can draw |
- // the content in it. |
- swap_frame = std::move(frame); |
- } |
- |
- sync_client_->SwapBuffers(output_surface_id_, std::move(swap_frame)); |
- DeliverMessages(); |
- did_swap_ = true; |
-} |
- |
-void SynchronousCompositorOutputSurface::CancelFallbackTick() { |
- fallback_tick_.Cancel(); |
- fallback_tick_pending_ = false; |
-} |
- |
-void SynchronousCompositorOutputSurface::FallbackTickFired() { |
- DCHECK(CalledOnValidThread()); |
- TRACE_EVENT0("renderer", |
- "SynchronousCompositorOutputSurface::FallbackTickFired"); |
- base::AutoReset<bool> in_fallback_tick(&fallback_tick_running_, true); |
- SkBitmap bitmap; |
- bitmap.allocN32Pixels(1, 1); |
- bitmap.eraseColor(0); |
- SkCanvas canvas(bitmap); |
- fallback_tick_pending_ = false; |
- DemandDrawSw(&canvas); |
-} |
- |
-void SynchronousCompositorOutputSurface::Invalidate() { |
- DCHECK(CalledOnValidThread()); |
- if (sync_client_) |
- sync_client_->Invalidate(); |
- |
- if (!fallback_tick_pending_) { |
- fallback_tick_.Reset( |
- base::Bind(&SynchronousCompositorOutputSurface::FallbackTickFired, |
- base::Unretained(this))); |
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
- FROM_HERE, fallback_tick_.callback(), |
- base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); |
- fallback_tick_pending_ = true; |
- } |
-} |
- |
-void SynchronousCompositorOutputSurface::BindFramebuffer() { |
- // This is a delegating output surface, no framebuffer/direct drawing support. |
- NOTREACHED(); |
-} |
- |
-uint32_t SynchronousCompositorOutputSurface::GetFramebufferCopyTextureFormat() { |
- // This is a delegating output surface, no framebuffer/direct drawing support. |
- NOTREACHED(); |
- return 0; |
-} |
- |
-void SynchronousCompositorOutputSurface::DemandDrawHw( |
- const gfx::Size& viewport_size, |
- const gfx::Rect& viewport_rect_for_tile_priority, |
- const gfx::Transform& transform_for_tile_priority) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(HasClient()); |
- DCHECK(context_provider_.get()); |
- CancelFallbackTick(); |
- |
- client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority, |
- transform_for_tile_priority); |
- InvokeComposite(gfx::Transform(), gfx::Rect(viewport_size)); |
-} |
- |
-void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(canvas); |
- DCHECK(!current_sw_canvas_); |
- CancelFallbackTick(); |
- |
- base::AutoReset<SkCanvas*> canvas_resetter(¤t_sw_canvas_, canvas); |
- |
- SkIRect canvas_clip; |
- canvas->getClipDeviceBounds(&canvas_clip); |
- gfx::Rect viewport = gfx::SkIRectToRect(canvas_clip); |
- |
- gfx::Transform transform(gfx::Transform::kSkipInitialization); |
- transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4. |
- |
- base::AutoReset<bool> set_in_software_draw(&in_software_draw_, true); |
- display_->SetExternalViewport(viewport); |
- display_->SetExternalClip(viewport); |
- software_output_surface_->SetSurfaceSize( |
- gfx::SkISizeToSize(canvas->getBaseLayerSize())); |
- InvokeComposite(transform, viewport); |
-} |
- |
-void SynchronousCompositorOutputSurface::InvokeComposite( |
- const gfx::Transform& transform, |
- const gfx::Rect& viewport) { |
- gfx::Transform adjusted_transform = transform; |
- adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0); |
- did_swap_ = false; |
- client_->OnDraw(adjusted_transform, viewport, in_software_draw_); |
- |
- if (did_swap_) { |
- // This must happen after unwinding the stack and leaving the compositor. |
- // Usually it is a separate task but we just defer it until OnDraw completes |
- // instead. |
- client_->DidSwapBuffersComplete(); |
- } |
-} |
- |
-void SynchronousCompositorOutputSurface::OnReclaimResources( |
- uint32_t output_surface_id, |
- const cc::ReturnedResourceArray& resources) { |
- // Ignore message if it's a stale one coming from a different output surface |
- // (e.g. after a lost context). |
- if (output_surface_id != output_surface_id_) |
- return; |
- client_->ReclaimResources(resources); |
-} |
- |
-void SynchronousCompositorOutputSurface::SetMemoryPolicy(size_t bytes_limit) { |
- DCHECK(CalledOnValidThread()); |
- bool became_zero = memory_policy_.bytes_limit_when_visible && !bytes_limit; |
- bool became_non_zero = |
- !memory_policy_.bytes_limit_when_visible && bytes_limit; |
- memory_policy_.bytes_limit_when_visible = bytes_limit; |
- memory_policy_.num_resources_limit = kNumResourcesLimit; |
- |
- if (client_) |
- client_->SetMemoryPolicy(memory_policy_); |
- |
- if (became_zero) { |
- // This is small hack to drop context resources without destroying it |
- // when this compositor is put into the background. |
- context_provider()->ContextSupport()->SetAggressivelyFreeResources( |
- true /* aggressively_free_resources */); |
- } else if (became_non_zero) { |
- context_provider()->ContextSupport()->SetAggressivelyFreeResources( |
- false /* aggressively_free_resources */); |
- } |
-} |
- |
-void SynchronousCompositorOutputSurface::DidActivatePendingTree() { |
- DCHECK(CalledOnValidThread()); |
- if (sync_client_) |
- sync_client_->DidActivatePendingTree(); |
- DeliverMessages(); |
-} |
- |
-void SynchronousCompositorOutputSurface::DeliverMessages() { |
- std::vector<std::unique_ptr<IPC::Message>> messages; |
- std::unique_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope = |
- frame_swap_message_queue_->AcquireSendMessageScope(); |
- frame_swap_message_queue_->DrainMessages(&messages); |
- for (auto& msg : messages) { |
- Send(msg.release()); |
- } |
-} |
- |
-bool SynchronousCompositorOutputSurface::Send(IPC::Message* message) { |
- DCHECK(CalledOnValidThread()); |
- return sender_->Send(message); |
-} |
- |
-bool SynchronousCompositorOutputSurface::CalledOnValidThread() const { |
- return thread_checker_.CalledOnValidThread(); |
-} |
- |
-void SynchronousCompositorOutputSurface::ReturnResources( |
- const cc::ReturnedResourceArray& resources) { |
- DCHECK(resources.empty()); |
- client_->ReclaimResources(resources); |
-} |
- |
-void SynchronousCompositorOutputSurface::SetBeginFrameSource( |
- cc::BeginFrameSource* begin_frame_source) { |
- // Software output is synchronous and doesn't use a BeginFrameSource. |
- NOTREACHED(); |
-} |
- |
-} // namespace content |