summaryrefslogtreecommitdiff
path: root/chromium/cc/surfaces/display.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/surfaces/display.cc')
-rw-r--r--chromium/cc/surfaces/display.cc145
1 files changed, 113 insertions, 32 deletions
diff --git a/chromium/cc/surfaces/display.cc b/chromium/cc/surfaces/display.cc
index 6866cedc9cf..4776df1bf14 100644
--- a/chromium/cc/surfaces/display.cc
+++ b/chromium/cc/surfaces/display.cc
@@ -6,7 +6,7 @@
#include <stddef.h>
-#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "cc/debug/benchmark_instrumentation.h"
#include "cc/output/compositor_frame.h"
@@ -24,50 +24,98 @@
#include "gpu/command_buffer/client/gles2_interface.h"
#include "ui/gfx/buffer_types.h"
+#if defined(ENABLE_VULKAN)
+#include "cc/output/vulkan_renderer.h"
+#endif
+
+namespace {
+
+class EmptyBeginFrameSource : public cc::BeginFrameSource {
+ public:
+ void DidFinishFrame(cc::BeginFrameObserver* obs,
+ size_t remaining_frames) override{};
+ void AddObserver(cc::BeginFrameObserver* obs) override{};
+ void RemoveObserver(cc::BeginFrameObserver* obs) override{};
+};
+
+} // namespace
+
namespace cc {
Display::Display(DisplayClient* client,
SurfaceManager* manager,
SharedBitmapManager* bitmap_manager,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- const RendererSettings& settings)
+ const RendererSettings& settings,
+ uint32_t compositor_surface_namespace)
: client_(client),
- manager_(manager),
+ surface_manager_(manager),
bitmap_manager_(bitmap_manager),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
settings_(settings),
+ compositor_surface_namespace_(compositor_surface_namespace),
device_scale_factor_(1.f),
swapped_since_resize_(false),
- scheduler_(nullptr),
+ vsync_begin_frame_source_(nullptr),
+ observed_begin_frame_source_(nullptr),
texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) {
- manager_->AddObserver(this);
+ surface_manager_->AddObserver(this);
}
Display::~Display() {
- manager_->RemoveObserver(this);
+ if (observed_begin_frame_source_)
+ surface_manager_->UnregisterBeginFrameSource(observed_begin_frame_source_);
+ surface_manager_->RemoveObserver(this);
if (aggregator_) {
for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
- Surface* surface = manager_->GetSurfaceForId(id_entry.first);
+ Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
if (surface)
surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED);
}
}
}
-bool Display::Initialize(scoped_ptr<OutputSurface> output_surface,
- DisplayScheduler* scheduler) {
- // TODO(enne): register/unregister BeginFrameSource with SurfaceManager here.
+void Display::CreateScheduler(base::SingleThreadTaskRunner* task_runner) {
+ DCHECK(!scheduler_);
+ if (!task_runner) {
+ // WebView doesn't have a task runner or a real begin frame source,
+ // so just create something fake here.
+ internal_begin_frame_source_.reset(new EmptyBeginFrameSource());
+ vsync_begin_frame_source_ = internal_begin_frame_source_.get();
+ observed_begin_frame_source_ = vsync_begin_frame_source_;
+ } else {
+ DCHECK(vsync_begin_frame_source_);
+
+ observed_begin_frame_source_ = vsync_begin_frame_source_;
+ if (settings_.disable_display_vsync) {
+ internal_begin_frame_source_.reset(
+ new BackToBackBeginFrameSource(task_runner));
+ observed_begin_frame_source_ = internal_begin_frame_source_.get();
+ }
+ }
+
+ scheduler_.reset(
+ new DisplayScheduler(this, observed_begin_frame_source_, task_runner,
+ output_surface_->capabilities().max_frames_pending));
+ surface_manager_->RegisterBeginFrameSource(observed_begin_frame_source_,
+ compositor_surface_namespace_);
+}
+
+bool Display::Initialize(std::unique_ptr<OutputSurface> output_surface,
+ base::SingleThreadTaskRunner* task_runner) {
output_surface_ = std::move(output_surface);
- scheduler_ = scheduler;
- return output_surface_->BindToClient(this);
+ if (!output_surface_->BindToClient(this))
+ return false;
+ CreateScheduler(task_runner);
+ return true;
}
void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) {
+ DCHECK_EQ(id.id_namespace(), compositor_surface_namespace_);
if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor)
return;
TRACE_EVENT0("cc", "Display::SetSurfaceId");
-
current_surface_id_ = id;
device_scale_factor_ = device_scale_factor;
@@ -101,30 +149,56 @@ void Display::SetExternalClip(const gfx::Rect& clip) {
external_clip_ = clip;
}
+void Display::SetOutputIsSecure(bool secure) {
+ if (secure == output_is_secure_)
+ return;
+ output_is_secure_ = secure;
+
+ if (aggregator_) {
+ aggregator_->set_output_is_secure(secure);
+ // Force a redraw.
+ if (!current_surface_id_.is_null())
+ aggregator_->SetFullDamageForSurface(current_surface_id_);
+ }
+}
+
void Display::InitializeRenderer() {
if (resource_provider_)
return;
- scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
- output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_,
- nullptr, settings_.highp_threshold_min,
- settings_.texture_id_allocation_chunk_size,
- settings_.use_gpu_memory_buffer_resources,
- std::vector<unsigned>(static_cast<size_t>(gfx::BufferFormat::LAST) + 1,
- GL_TEXTURE_2D));
+ std::unique_ptr<ResourceProvider> resource_provider =
+ ResourceProvider::Create(
+ output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_,
+ nullptr, settings_.highp_threshold_min,
+ settings_.texture_id_allocation_chunk_size,
+ settings_.use_gpu_memory_buffer_resources,
+ std::vector<unsigned>(
+ static_cast<size_t>(gfx::BufferFormat::LAST) + 1, GL_TEXTURE_2D));
if (!resource_provider)
return;
if (output_surface_->context_provider()) {
- scoped_ptr<GLRenderer> renderer = GLRenderer::Create(
+ std::unique_ptr<GLRenderer> renderer = GLRenderer::Create(
this, &settings_, output_surface_.get(), resource_provider.get(),
texture_mailbox_deleter_.get(), settings_.highp_threshold_min);
if (!renderer)
return;
renderer_ = std::move(renderer);
+ } else if (output_surface_->vulkan_context_provider()) {
+#if defined(ENABLE_VULKAN)
+ std::unique_ptr<VulkanRenderer> renderer = VulkanRenderer::Create(
+ this, &settings_, output_surface_.get(), resource_provider.get(),
+ texture_mailbox_deleter_.get(), settings_.highp_threshold_min);
+ if (!renderer)
+ return;
+ renderer_ = std::move(renderer);
+#else
+ NOTREACHED();
+#endif
} else {
- scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create(
- this, &settings_, output_surface_.get(), resource_provider.get());
+ std::unique_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create(
+ this, &settings_, output_surface_.get(), resource_provider.get(),
+ true /* use_image_hijack_canvas */);
if (!renderer)
return;
renderer_ = std::move(renderer);
@@ -135,8 +209,9 @@ void Display::InitializeRenderer() {
// overlays.
bool output_partial_list = renderer_->Capabilities().using_partial_swap &&
!output_surface_->GetOverlayCandidateValidator();
- aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get(),
- output_partial_list));
+ aggregator_.reset(new SurfaceAggregator(
+ surface_manager_, resource_provider_.get(), output_partial_list));
+ aggregator_->set_output_is_secure(output_is_secure_);
}
void Display::DidLoseOutputSurface() {
@@ -148,7 +223,7 @@ void Display::DidLoseOutputSurface() {
}
void Display::UpdateRootSurfaceResourcesLocked() {
- Surface* surface = manager_->GetSurfaceForId(current_surface_id_);
+ Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_);
bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame();
if (scheduler_)
scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked);
@@ -168,7 +243,7 @@ bool Display::DrawAndSwap() {
return false;
}
- scoped_ptr<CompositorFrame> frame =
+ std::unique_ptr<CompositorFrame> frame =
aggregator_->Aggregate(current_surface_id_);
if (!frame) {
TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.",
@@ -178,7 +253,7 @@ bool Display::DrawAndSwap() {
// Run callbacks early to allow pipelining.
for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
- Surface* surface = manager_->GetSurfaceForId(id_entry.first);
+ Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
if (surface)
surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN);
}
@@ -276,9 +351,15 @@ void Display::DidSwapBuffersComplete() {
renderer_->SwapBuffersComplete();
}
-void Display::CommitVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) {
- client_->CommitVSyncParameters(timebase, interval);
+void Display::SetBeginFrameSource(BeginFrameSource* source) {
+ // It's expected that there's only a single source from the
+ // BrowserCompositorOutputSurface that corresponds to vsync. The BFS is
+ // passed BrowserCompositorOutputSurface -> Display -> DisplayScheduler as an
+ // input. DisplayScheduler makes a decision about which BFS to use and
+ // calls back to Display as DisplaySchedulerClient to register for that
+ // surface id.
+ DCHECK(!vsync_begin_frame_source_);
+ vsync_begin_frame_source_ = source;
}
void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
@@ -320,7 +401,7 @@ void Display::SetFullRootLayerDamage() {
void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) {
if (aggregator_ &&
aggregator_->previous_contained_surfaces().count(surface_id)) {
- Surface* surface = manager_->GetSurfaceForId(surface_id);
+ Surface* surface = surface_manager_->GetSurfaceForId(surface_id);
if (surface) {
const CompositorFrame* current_frame = surface->GetEligibleFrame();
if (!current_frame || !current_frame->delegated_frame_data ||