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/debug/trace_event.h"
8 #include "base/message_loop/message_loop.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"
25 Display::Display(DisplayClient
* client
,
26 SurfaceManager
* manager
,
27 SharedBitmapManager
* bitmap_manager
,
28 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager
,
29 const RendererSettings
& settings
)
32 bitmap_manager_(bitmap_manager
),
33 gpu_memory_buffer_manager_(gpu_memory_buffer_manager
),
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);
44 manager_
->RemoveObserver(this);
47 bool Display::Initialize(scoped_ptr
<OutputSurface
> output_surface
) {
48 output_surface_
= output_surface
.Pass();
49 return output_surface_
->BindToClient(this);
52 void Display::Resize(SurfaceId id
,
53 const gfx::Size
& size
,
54 float device_scale_factor
) {
55 current_surface_id_
= id
;
56 current_surface_size_
= size
;
57 device_scale_factor_
= device_scale_factor
;
58 client_
->DisplayDamaged();
61 void Display::InitializeRenderer() {
62 if (resource_provider_
)
65 scoped_ptr
<ResourceProvider
> resource_provider
= ResourceProvider::Create(
66 output_surface_
.get(), bitmap_manager_
, gpu_memory_buffer_manager_
,
67 blocking_main_thread_task_runner_
.get(), settings_
.highp_threshold_min
,
68 settings_
.use_rgba_4444_textures
,
69 settings_
.texture_id_allocation_chunk_size
);
70 if (!resource_provider
)
73 if (output_surface_
->context_provider()) {
74 scoped_ptr
<GLRenderer
> renderer
= GLRenderer::Create(
75 this, &settings_
, output_surface_
.get(), resource_provider
.get(),
76 texture_mailbox_deleter_
.get(), settings_
.highp_threshold_min
);
79 renderer_
= renderer
.Pass();
81 scoped_ptr
<SoftwareRenderer
> renderer
= SoftwareRenderer::Create(
82 this, &settings_
, output_surface_
.get(), resource_provider
.get());
85 renderer_
= renderer
.Pass();
88 resource_provider_
= resource_provider
.Pass();
89 aggregator_
.reset(new SurfaceAggregator(manager_
, resource_provider_
.get()));
92 void Display::DidLoseOutputSurface() {
93 client_
->OutputSurfaceLost();
96 bool Display::Draw() {
97 if (current_surface_id_
.is_null())
100 InitializeRenderer();
101 if (!output_surface_
)
104 // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks
105 // while Aggregate is called to immediately run release callbacks afterward.
106 scoped_ptr
<CompositorFrame
> frame
=
107 aggregator_
->Aggregate(current_surface_id_
);
111 TRACE_EVENT0("cc", "Display::Draw");
112 benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
113 DelegatedFrameData
* frame_data
= frame
->delegated_frame_data
.get();
115 gfx::Rect device_viewport_rect
= gfx::Rect(current_surface_size_
);
116 gfx::Rect device_clip_rect
= device_viewport_rect
;
117 bool disable_picture_quad_image_filtering
= false;
119 renderer_
->DecideRenderPassAllocationsForFrame(frame_data
->render_pass_list
);
120 renderer_
->DrawFrame(&frame_data
->render_pass_list
,
121 device_scale_factor_
,
122 device_viewport_rect
,
124 disable_picture_quad_image_filtering
);
125 renderer_
->SwapBuffers(frame
->metadata
);
126 for (SurfaceAggregator::SurfaceIndexMap::iterator it
=
127 aggregator_
->previous_contained_surfaces().begin();
128 it
!= aggregator_
->previous_contained_surfaces().end();
130 Surface
* surface
= manager_
->GetSurfaceForId(it
->first
);
132 surface
->RunDrawCallbacks();
137 void Display::DidSwapBuffers() {
138 client_
->DidSwapBuffers();
141 void Display::DidSwapBuffersComplete() {
142 client_
->DidSwapBuffersComplete();
145 void Display::CommitVSyncParameters(base::TimeTicks timebase
,
146 base::TimeDelta interval
) {
147 client_
->CommitVSyncParameters(timebase
, interval
);
150 void Display::SetMemoryPolicy(const ManagedMemoryPolicy
& policy
) {
151 client_
->SetMemoryPolicy(policy
);
154 void Display::OnSurfaceDamaged(SurfaceId surface
) {
155 if (aggregator_
&& aggregator_
->previous_contained_surfaces().count(surface
))
156 client_
->DisplayDamaged();
159 SurfaceId
Display::CurrentSurfaceId() {
160 return current_surface_id_
;
163 int Display::GetMaxFramesPending() {
164 if (!output_surface_
)
165 return OutputSurface::DEFAULT_MAX_FRAMES_PENDING
;
166 return output_surface_
->capabilities().max_frames_pending
;