• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "cc/surfaces/display.h"
6 
7 #include "base/debug/trace_event.h"
8 #include "base/message_loop/message_loop.h"
9 #include "cc/output/compositor_frame.h"
10 #include "cc/output/compositor_frame_ack.h"
11 #include "cc/output/direct_renderer.h"
12 #include "cc/output/gl_renderer.h"
13 #include "cc/output/software_renderer.h"
14 #include "cc/surfaces/display_client.h"
15 #include "cc/surfaces/surface.h"
16 #include "cc/surfaces/surface_aggregator.h"
17 #include "cc/surfaces/surface_manager.h"
18 #include "cc/trees/blocking_task_runner.h"
19 
20 namespace cc {
21 
Display(DisplayClient * client,SurfaceManager * manager,SharedBitmapManager * bitmap_manager)22 Display::Display(DisplayClient* client,
23                  SurfaceManager* manager,
24                  SharedBitmapManager* bitmap_manager)
25     : client_(client),
26       manager_(manager),
27       bitmap_manager_(bitmap_manager),
28       blocking_main_thread_task_runner_(
29           BlockingTaskRunner::Create(base::MessageLoopProxy::current())) {
30   manager_->AddObserver(this);
31 }
32 
~Display()33 Display::~Display() {
34   manager_->RemoveObserver(this);
35 }
36 
Resize(SurfaceId id,const gfx::Size & size)37 void Display::Resize(SurfaceId id, const gfx::Size& size) {
38   current_surface_id_ = id;
39   current_surface_size_ = size;
40   client_->DisplayDamaged();
41 }
42 
InitializeOutputSurface()43 void Display::InitializeOutputSurface() {
44   if (output_surface_)
45     return;
46   scoped_ptr<OutputSurface> output_surface = client_->CreateOutputSurface();
47   if (!output_surface->BindToClient(this))
48     return;
49 
50   int highp_threshold_min = 0;
51   bool use_rgba_4444_texture_format = false;
52   size_t id_allocation_chunk_size = 1;
53   bool use_distance_field_text = false;
54   scoped_ptr<ResourceProvider> resource_provider =
55       ResourceProvider::Create(output_surface.get(),
56                                bitmap_manager_,
57                                blocking_main_thread_task_runner_.get(),
58                                highp_threshold_min,
59                                use_rgba_4444_texture_format,
60                                id_allocation_chunk_size,
61                                use_distance_field_text);
62   if (!resource_provider)
63     return;
64 
65   if (output_surface->context_provider()) {
66     TextureMailboxDeleter* texture_mailbox_deleter = NULL;
67     scoped_ptr<GLRenderer> renderer =
68         GLRenderer::Create(this,
69                            &settings_,
70                            output_surface.get(),
71                            resource_provider.get(),
72                            texture_mailbox_deleter,
73                            highp_threshold_min);
74     if (!renderer)
75       return;
76     renderer_ = renderer.Pass();
77   } else {
78     scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create(
79         this, &settings_, output_surface.get(), resource_provider.get());
80     if (!renderer)
81       return;
82     renderer_ = renderer.Pass();
83   }
84 
85   output_surface_ = output_surface.Pass();
86   resource_provider_ = resource_provider.Pass();
87   aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get()));
88 }
89 
Draw()90 bool Display::Draw() {
91   if (current_surface_id_.is_null())
92     return false;
93 
94   InitializeOutputSurface();
95   if (!output_surface_)
96     return false;
97 
98   // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks
99   // while Aggregate is called to immediately run release callbacks afterward.
100   scoped_ptr<CompositorFrame> frame =
101       aggregator_->Aggregate(current_surface_id_);
102   if (!frame)
103     return false;
104 
105   TRACE_EVENT0("cc", "Display::Draw");
106   DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
107 
108   // Only reshape when we know we are going to draw. Otherwise, the reshape
109   // can leave the window at the wrong size if we never draw and the proper
110   // viewport size is never set.
111   output_surface_->Reshape(current_surface_size_, 1.f);
112   float device_scale_factor = 1.0f;
113   gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_);
114   gfx::Rect device_clip_rect = device_viewport_rect;
115   bool disable_picture_quad_image_filtering = false;
116 
117   renderer_->DecideRenderPassAllocationsForFrame(frame_data->render_pass_list);
118   renderer_->DrawFrame(&frame_data->render_pass_list,
119                        device_scale_factor,
120                        device_viewport_rect,
121                        device_clip_rect,
122                        disable_picture_quad_image_filtering);
123   renderer_->SwapBuffers(frame->metadata);
124   for (SurfaceAggregator::SurfaceIndexMap::iterator it =
125            aggregator_->previous_contained_surfaces().begin();
126        it != aggregator_->previous_contained_surfaces().end();
127        ++it) {
128     Surface* surface = manager_->GetSurfaceForId(it->first);
129     if (surface)
130       surface->RunDrawCallbacks();
131   }
132   return true;
133 }
134 
DidSwapBuffers()135 void Display::DidSwapBuffers() {
136   client_->DidSwapBuffers();
137 }
138 
DidSwapBuffersComplete()139 void Display::DidSwapBuffersComplete() {
140   client_->DidSwapBuffersComplete();
141 }
142 
CommitVSyncParameters(base::TimeTicks timebase,base::TimeDelta interval)143 void Display::CommitVSyncParameters(base::TimeTicks timebase,
144                                     base::TimeDelta interval) {
145   client_->CommitVSyncParameters(timebase, interval);
146 }
147 
OnSurfaceDamaged(SurfaceId surface)148 void Display::OnSurfaceDamaged(SurfaceId surface) {
149   if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface))
150     client_->DisplayDamaged();
151 }
152 
CurrentSurfaceId()153 SurfaceId Display::CurrentSurfaceId() {
154   return current_surface_id_;
155 }
156 
GetMaxFramesPending()157 int Display::GetMaxFramesPending() {
158   if (!output_surface_)
159     return OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
160   return output_surface_->capabilities().max_frames_pending;
161 }
162 
163 }  // namespace cc
164