| 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
|
|
|