Infer appropriate GNU_STACK alignment for a shared library.
[chromium-blink-merge.git] / cc / surfaces / display.cc
blobab1f0afcdf7790e08433b4d867c31a3d0c9eb9b4
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/surfaces/display.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/trace_event/trace_event.h"
9 #include "cc/debug/benchmark_instrumentation.h"
10 #include "cc/output/compositor_frame.h"
11 #include "cc/output/compositor_frame_ack.h"
12 #include "cc/output/direct_renderer.h"
13 #include "cc/output/gl_renderer.h"
14 #include "cc/output/renderer_settings.h"
15 #include "cc/output/software_renderer.h"
16 #include "cc/resources/texture_mailbox_deleter.h"
17 #include "cc/surfaces/display_client.h"
18 #include "cc/surfaces/surface.h"
19 #include "cc/surfaces/surface_aggregator.h"
20 #include "cc/surfaces/surface_manager.h"
21 #include "cc/trees/blocking_task_runner.h"
23 namespace cc {
25 Display::Display(DisplayClient* client,
26 SurfaceManager* manager,
27 SharedBitmapManager* bitmap_manager,
28 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
29 const RendererSettings& settings)
30 : client_(client),
31 manager_(manager),
32 bitmap_manager_(bitmap_manager),
33 gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
34 settings_(settings),
35 device_scale_factor_(1.f),
36 blocking_main_thread_task_runner_(
37 BlockingTaskRunner::Create(base::MessageLoopProxy::current())),
38 texture_mailbox_deleter_(
39 new TextureMailboxDeleter(base::MessageLoopProxy::current())) {
40 manager_->AddObserver(this);
43 Display::~Display() {
44 manager_->RemoveObserver(this);
45 if (aggregator_) {
46 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
47 Surface* surface = manager_->GetSurfaceForId(id_entry.first);
48 if (surface)
49 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED);
54 bool Display::Initialize(scoped_ptr<OutputSurface> output_surface) {
55 output_surface_ = output_surface.Pass();
56 return output_surface_->BindToClient(this);
59 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) {
60 current_surface_id_ = id;
61 device_scale_factor_ = device_scale_factor;
62 client_->DisplayDamaged();
65 void Display::Resize(const gfx::Size& size) {
66 if (size == current_surface_size_)
67 return;
68 // Need to ensure all pending swaps have executed before the window is
69 // resized, or D3D11 will scale the swap output.
70 if (renderer_ && settings_.finish_rendering_on_resize)
71 renderer_->Finish();
72 current_surface_size_ = size;
73 client_->DisplayDamaged();
76 void Display::InitializeRenderer() {
77 if (resource_provider_)
78 return;
80 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
81 output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_,
82 blocking_main_thread_task_runner_.get(), settings_.highp_threshold_min,
83 settings_.use_rgba_4444_textures,
84 settings_.texture_id_allocation_chunk_size);
85 if (!resource_provider)
86 return;
88 if (output_surface_->context_provider()) {
89 scoped_ptr<GLRenderer> renderer = GLRenderer::Create(
90 this, &settings_, output_surface_.get(), resource_provider.get(),
91 texture_mailbox_deleter_.get(), settings_.highp_threshold_min);
92 if (!renderer)
93 return;
94 renderer_ = renderer.Pass();
95 } else {
96 scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create(
97 this, &settings_, output_surface_.get(), resource_provider.get());
98 if (!renderer)
99 return;
100 renderer_ = renderer.Pass();
103 resource_provider_ = resource_provider.Pass();
104 aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get()));
107 void Display::DidLoseOutputSurface() {
108 client_->OutputSurfaceLost();
111 bool Display::Draw() {
112 if (current_surface_id_.is_null())
113 return false;
115 InitializeRenderer();
116 if (!output_surface_)
117 return false;
119 // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks
120 // while Aggregate is called to immediately run release callbacks afterward.
121 scoped_ptr<CompositorFrame> frame =
122 aggregator_->Aggregate(current_surface_id_);
123 if (!frame)
124 return false;
126 TRACE_EVENT0("cc", "Display::Draw");
127 benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
129 // Run callbacks early to allow pipelining.
130 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
131 Surface* surface = manager_->GetSurfaceForId(id_entry.first);
132 if (surface)
133 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN);
135 DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
137 gfx::Size surface_size =
138 frame_data->render_pass_list.back()->output_rect.size();
140 gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_);
141 gfx::Rect device_clip_rect = device_viewport_rect;
142 bool disable_picture_quad_image_filtering = false;
144 renderer_->DecideRenderPassAllocationsForFrame(frame_data->render_pass_list);
145 renderer_->DrawFrame(&frame_data->render_pass_list,
146 device_scale_factor_,
147 device_viewport_rect,
148 device_clip_rect,
149 disable_picture_quad_image_filtering);
151 if (surface_size != current_surface_size_) {
152 DidSwapBuffers();
153 DidSwapBuffersComplete();
154 } else {
155 renderer_->SwapBuffers(frame->metadata);
158 return true;
161 void Display::DidSwapBuffers() {
162 client_->DidSwapBuffers();
165 void Display::DidSwapBuffersComplete() {
166 client_->DidSwapBuffersComplete();
169 void Display::CommitVSyncParameters(base::TimeTicks timebase,
170 base::TimeDelta interval) {
171 client_->CommitVSyncParameters(timebase, interval);
174 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
175 client_->SetMemoryPolicy(policy);
178 void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) {
179 if (aggregator_ &&
180 aggregator_->previous_contained_surfaces().count(surface_id)) {
181 Surface* surface = manager_->GetSurfaceForId(surface_id);
182 if (surface) {
183 const CompositorFrame* current_frame = surface->GetEligibleFrame();
184 if (!current_frame || !current_frame->delegated_frame_data ||
185 !current_frame->delegated_frame_data->resource_list.size())
186 aggregator_->ReleaseResources(surface_id);
188 client_->DisplayDamaged();
189 *changed = true;
190 } else if (surface_id == current_surface_id_) {
191 client_->DisplayDamaged();
192 *changed = true;
196 SurfaceId Display::CurrentSurfaceId() {
197 return current_surface_id_;
200 int Display::GetMaxFramesPending() {
201 int max_frames_pending =
202 output_surface_ ? output_surface_->capabilities().max_frames_pending : 0;
203 if (max_frames_pending <= 0)
204 max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
205 return max_frames_pending;
208 } // namespace cc