| 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
|
| index 37d3a23e90fc15f328e5346443836f00898cf0f9..b5b7ee9c00ce59354d8c9f551efbaa55428db4d5 100644
|
| --- a/content/renderer/android/synchronous_compositor_output_surface.cc
|
| +++ b/content/renderer/android/synchronous_compositor_output_surface.cc
|
| @@ -16,7 +16,13 @@
|
| #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"
|
| @@ -38,39 +44,42 @@ namespace content {
|
| namespace {
|
|
|
| const int64_t kFallbackTickTimeoutInMilliseconds = 100;
|
| +const uint32_t kCompositorSurfaceNamespace = 1;
|
|
|
| // Do not limit number of resources, so use an unrealistically high value.
|
| const size_t kNumResourcesLimit = 10 * 1000 * 1000;
|
|
|
| } // namespace
|
|
|
| -class SynchronousCompositorOutputSurface::SoftwareDevice
|
| - : public cc::SoftwareOutputDevice {
|
| +class SoftwareDevice : public cc::SoftwareOutputDevice {
|
| public:
|
| - SoftwareDevice(SynchronousCompositorOutputSurface* surface)
|
| - : surface_(surface) {
|
| - }
|
| + 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 {
|
| - if (!surface_->current_sw_canvas_) {
|
| - NOTREACHED() << "BeginPaint with no canvas set";
|
| - return &null_canvas_;
|
| - }
|
| - LOG_IF(WARNING, surface_->did_swap_)
|
| - << "Mutliple calls to BeginPaint per frame";
|
| - return surface_->current_sw_canvas_;
|
| + DCHECK(*canvas_) << "BeginPaint with no canvas set";
|
| + return *canvas_;
|
| }
|
| void EndPaint() override {}
|
|
|
| private:
|
| - SynchronousCompositorOutputSurface* surface_;
|
| - SkCanvas null_canvas_;
|
| + SkCanvas** canvas_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(SoftwareDevice);
|
| };
|
|
|
| +class 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 {}
|
| +};
|
| +
|
| SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
|
| scoped_refptr<cc::ContextProvider> context_provider,
|
| scoped_refptr<cc::ContextProvider> worker_context_provider,
|
| @@ -80,19 +89,17 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
|
| scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue)
|
| : cc::OutputSurface(std::move(context_provider),
|
| std::move(worker_context_provider),
|
| - base::MakeUnique<SoftwareDevice>(this)),
|
| + nullptr),
|
| routing_id_(routing_id),
|
| output_surface_id_(output_surface_id),
|
| registry_(registry),
|
| sender_(RenderThreadImpl::current()->sync_compositor_message_filter()),
|
| - registered_(false),
|
| - sync_client_(nullptr),
|
| - current_sw_canvas_(nullptr),
|
| memory_policy_(0u),
|
| - did_swap_(false),
|
| frame_swap_message_queue_(frame_swap_message_queue),
|
| - fallback_tick_pending_(false),
|
| - fallback_tick_running_(false) {
|
| + surface_manager_(new cc::SurfaceManager),
|
| + surface_id_allocator_(
|
| + new cc::SurfaceIdAllocator(kCompositorSurfaceNamespace)),
|
| + surface_factory_(new cc::SurfaceFactory(surface_manager_.get(), this)) {
|
| DCHECK(registry_);
|
| DCHECK(sender_);
|
| thread_checker_.DetachFromThread();
|
| @@ -100,6 +107,7 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
|
| capabilities_.delegated_rendering = true;
|
| memory_policy_.priority_cutoff_when_visible =
|
| gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
|
| + surface_id_allocator_->RegisterSurfaceIdNamespace(surface_manager_.get());
|
| }
|
|
|
| SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {}
|
| @@ -135,6 +143,24 @@ bool SynchronousCompositorOutputSurface::BindToClient(
|
| base::Unretained(this)));
|
| registry_->RegisterOutputSurface(routing_id_, this);
|
| registered_ = true;
|
| +
|
| + surface_manager_->RegisterSurfaceFactoryClient(
|
| + surface_id_allocator_->id_namespace(), this);
|
| +
|
| + cc::RendererSettings software_renderer_settings;
|
| +
|
| + // 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(
|
| + surface_manager_.get(), nullptr /* shared_bitmap_manager */,
|
| + nullptr /* gpu_memory_buffer_manager */, software_renderer_settings,
|
| + surface_id_allocator_->id_namespace(), nullptr /* begin_frame_source */,
|
| + base::MakeUnique<SoftwareOutputSurface>(
|
| + base::MakeUnique<SoftwareDevice>(¤t_sw_canvas_)),
|
| + nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */));
|
| + display_->Initialize(&display_client_);
|
| return true;
|
| }
|
|
|
| @@ -144,6 +170,14 @@ void SynchronousCompositorOutputSurface::DetachFromClient() {
|
| 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_->id_namespace());
|
| + display_ = nullptr;
|
| + surface_factory_ = nullptr;
|
| + surface_id_allocator_ = nullptr;
|
| + surface_manager_ = nullptr;
|
| cc::OutputSurface::DetachFromClient();
|
| CancelFallbackTick();
|
| }
|
| @@ -156,12 +190,41 @@ void SynchronousCompositorOutputSurface::Reshape(
|
| // Intentional no-op: surface size is controlled by the embedder.
|
| }
|
|
|
| +static void NoOpDrawCallback(cc::SurfaceDrawStatus s) {}
|
| +
|
| void SynchronousCompositorOutputSurface::SwapBuffers(
|
| cc::CompositorFrame frame) {
|
| DCHECK(CalledOnValidThread());
|
| DCHECK(sync_client_);
|
| +
|
| + 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 {
|
| + swap_frame = std::move(frame);
|
| + }
|
| +
|
| if (!fallback_tick_running_) {
|
| - sync_client_->SwapBuffers(output_surface_id_, std::move(frame));
|
| + sync_client_->SwapBuffers(output_surface_id_, std::move(swap_frame));
|
| DeliverMessages();
|
| }
|
| client_->DidSwapBuffers();
|
| @@ -228,8 +291,7 @@ void SynchronousCompositorOutputSurface::DemandDrawHw(
|
| surface_size_ = surface_size;
|
| client_->SetExternalTilePriorityConstraints(viewport_rect_for_tile_priority,
|
| transform_for_tile_priority);
|
| - const bool software_draw = false;
|
| - InvokeComposite(transform, viewport, clip, software_draw);
|
| + InvokeComposite(transform, viewport, clip);
|
| }
|
|
|
| void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
|
| @@ -249,19 +311,18 @@ void SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
|
|
|
| surface_size_ = gfx::Size(canvas->getBaseLayerSize().width(),
|
| canvas->getBaseLayerSize().height());
|
| - const bool software_draw = true;
|
| - InvokeComposite(transform, clip, clip, software_draw);
|
| + base::AutoReset<bool> set_in_software_draw(&in_software_draw_, true);
|
| + InvokeComposite(transform, clip, clip);
|
| }
|
|
|
| void SynchronousCompositorOutputSurface::InvokeComposite(
|
| const gfx::Transform& transform,
|
| const gfx::Rect& viewport,
|
| - const gfx::Rect& clip,
|
| - bool software_draw) {
|
| + const gfx::Rect& clip) {
|
| gfx::Transform adjusted_transform = transform;
|
| adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
|
| did_swap_ = false;
|
| - client_->OnDraw(adjusted_transform, viewport, clip, software_draw);
|
| + client_->OnDraw(adjusted_transform, viewport, clip, in_software_draw_);
|
|
|
| if (did_swap_)
|
| client_->DidSwapBuffersComplete();
|
| @@ -325,4 +386,17 @@ bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
|
| return thread_checker_.CalledOnValidThread();
|
| }
|
|
|
| +void SynchronousCompositorOutputSurface::ReturnResources(
|
| + const cc::ReturnedResourceArray& resources) {
|
| + DCHECK(resources.empty());
|
| + cc::CompositorFrameAck ack;
|
| + client_->ReclaimResources(&ack);
|
| +}
|
| +
|
| +void SynchronousCompositorOutputSurface::SetBeginFrameSource(
|
| + cc::BeginFrameSource* begin_frame_source) {
|
| + // Software output is synchronous and doesn't use a BeginFrameSource.
|
| + NOTREACHED();
|
| +}
|
| +
|
| } // namespace content
|
|
|