Automated Commit: Committing new LKGM version 6953.0.0 for chromeos.
[chromium-blink-merge.git] / cc / surfaces / display.cc
blob853dfb64bb7a40ac5631df8d7ef691f0973767be
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 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(),
138 stored_latency_info_.begin(),
139 stored_latency_info_.end());
140 stored_latency_info_.clear();
141 bool have_copy_requests = false;
142 for (const auto* pass : frame_data->render_pass_list) {
143 have_copy_requests |= !pass->copy_requests.empty();
146 gfx::Size surface_size;
147 bool have_damage = false;
148 if (!frame_data->render_pass_list.empty()) {
149 surface_size = frame_data->render_pass_list.back()->output_rect.size();
150 have_damage =
151 !frame_data->render_pass_list.back()->damage_rect.size().IsEmpty();
153 bool avoid_swap = surface_size != current_surface_size_;
154 bool should_draw = !frame->metadata.latency_info.empty() ||
155 have_copy_requests || (have_damage && !avoid_swap);
157 if (should_draw) {
158 gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_);
159 gfx::Rect device_clip_rect = device_viewport_rect;
160 bool disable_picture_quad_image_filtering = false;
162 renderer_->DecideRenderPassAllocationsForFrame(
163 frame_data->render_pass_list);
164 renderer_->DrawFrame(&frame_data->render_pass_list, device_scale_factor_,
165 device_viewport_rect, device_clip_rect,
166 disable_picture_quad_image_filtering);
169 if (should_draw && !avoid_swap) {
170 renderer_->SwapBuffers(frame->metadata);
171 } else {
172 stored_latency_info_.insert(stored_latency_info_.end(),
173 frame->metadata.latency_info.begin(),
174 frame->metadata.latency_info.end());
175 DidSwapBuffers();
176 DidSwapBuffersComplete();
179 return true;
182 void Display::DidSwapBuffers() {
183 client_->DidSwapBuffers();
186 void Display::DidSwapBuffersComplete() {
187 client_->DidSwapBuffersComplete();
190 void Display::CommitVSyncParameters(base::TimeTicks timebase,
191 base::TimeDelta interval) {
192 client_->CommitVSyncParameters(timebase, interval);
195 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
196 client_->SetMemoryPolicy(policy);
199 void Display::OnDraw() {
200 NOTREACHED();
203 void Display::DeferredInitialize() {
204 NOTREACHED();
207 void Display::ReleaseGL() {
208 NOTREACHED();
211 void Display::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
212 NOTREACHED();
215 void Display::ReclaimResources(const CompositorFrameAck* ack) {
216 NOTREACHED();
219 void Display::SetExternalDrawConstraints(
220 const gfx::Transform& transform,
221 const gfx::Rect& viewport,
222 const gfx::Rect& clip,
223 const gfx::Rect& viewport_rect_for_tile_priority,
224 const gfx::Transform& transform_for_tile_priority,
225 bool resourceless_software_draw) {
226 NOTREACHED();
229 void Display::SetTreeActivationCallback(const base::Closure& callback) {
230 NOTREACHED();
233 void Display::SetFullRootLayerDamage() {
234 NOTREACHED();
237 void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) {
238 if (aggregator_ &&
239 aggregator_->previous_contained_surfaces().count(surface_id)) {
240 Surface* surface = manager_->GetSurfaceForId(surface_id);
241 if (surface) {
242 const CompositorFrame* current_frame = surface->GetEligibleFrame();
243 if (!current_frame || !current_frame->delegated_frame_data ||
244 !current_frame->delegated_frame_data->resource_list.size())
245 aggregator_->ReleaseResources(surface_id);
247 client_->DisplayDamaged();
248 *changed = true;
249 } else if (surface_id == current_surface_id_) {
250 client_->DisplayDamaged();
251 *changed = true;
255 SurfaceId Display::CurrentSurfaceId() {
256 return current_surface_id_;
259 int Display::GetMaxFramesPending() {
260 int max_frames_pending =
261 output_surface_ ? output_surface_->capabilities().max_frames_pending : 0;
262 if (max_frames_pending <= 0)
263 max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
264 return max_frames_pending;
267 } // namespace cc