OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CC_SURFACES_DISPLAY_H_ | 5 #ifndef CC_SURFACES_DISPLAY_H_ |
6 #define CC_SURFACES_DISPLAY_H_ | 6 #define CC_SURFACES_DISPLAY_H_ |
7 | 7 |
8 #include "cc/surfaces/display.h" | 8 #include "cc/surfaces/display.h" |
9 | 9 |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "cc/output/compositor_frame.h" | 11 #include "cc/output/compositor_frame.h" |
12 #include "cc/output/direct_renderer.h" | 12 #include "cc/output/direct_renderer.h" |
13 #include "cc/output/gl_renderer.h" | 13 #include "cc/output/gl_renderer.h" |
14 #include "cc/output/software_renderer.h" | |
14 #include "cc/surfaces/display_client.h" | 15 #include "cc/surfaces/display_client.h" |
15 #include "cc/surfaces/surface.h" | 16 #include "cc/surfaces/surface.h" |
16 #include "ui/gfx/frame_time.h" | |
17 | 17 |
18 namespace cc { | 18 namespace cc { |
19 static ResourceProvider::ResourceId ResourceRemapHelper( | |
jamesr
2014/06/10 23:38:55
nit: blank line between namespace and function
| |
20 bool* invalid_frame, | |
21 const ResourceProvider::ResourceIdMap& child_to_parent_map, | |
22 ResourceProvider::ResourceIdArray* resources_in_frame, | |
23 ResourceProvider::ResourceId id) { | |
24 ResourceProvider::ResourceIdMap::const_iterator it = | |
25 child_to_parent_map.find(id); | |
26 if (it == child_to_parent_map.end()) { | |
27 *invalid_frame = true; | |
28 return 0; | |
29 } | |
30 | |
31 DCHECK_EQ(it->first, id); | |
32 ResourceProvider::ResourceId remapped_id = it->second; | |
33 resources_in_frame->push_back(id); | |
34 return remapped_id; | |
35 } | |
19 | 36 |
20 Display::Display(DisplayClient* client, | 37 Display::Display(DisplayClient* client, |
21 SurfaceManager* manager, | 38 SurfaceManager* manager, |
22 SharedBitmapManager* bitmap_manager) | 39 SharedBitmapManager* bitmap_manager) |
23 : scheduled_draw_(false), | 40 : client_(client), |
24 client_(client), | |
25 manager_(manager), | 41 manager_(manager), |
26 aggregator_(manager), | 42 aggregator_(manager), |
27 bitmap_manager_(bitmap_manager), | 43 bitmap_manager_(bitmap_manager) { |
28 schedule_draw_factory_(this) { | |
29 } | 44 } |
30 | 45 |
31 Display::~Display() { | 46 Display::~Display() { |
32 } | 47 } |
33 | 48 |
34 void Display::Resize(const gfx::Size& size) { | 49 void Display::Resize(const gfx::Size& size) { |
35 current_surface_.reset(new Surface(manager_, this, size)); | 50 current_surface_.reset(new Surface(manager_, this, size)); |
36 } | 51 } |
37 | 52 |
53 void Display::InitializeOutputSurface() { | |
54 if (output_surface_) | |
55 return; | |
56 scoped_ptr<OutputSurface> output_surface = client_->CreateOutputSurface(); | |
57 if (!output_surface->BindToClient(this)) | |
58 return; | |
59 | |
60 int highp_threshold_min = 0; | |
61 bool use_rgba_4444_texture_format = false; | |
62 size_t id_allocation_chunk_size = 1; | |
63 bool use_distance_field_text = false; | |
64 scoped_ptr<ResourceProvider> resource_provider = | |
65 ResourceProvider::Create(output_surface.get(), | |
66 bitmap_manager_, | |
67 highp_threshold_min, | |
68 use_rgba_4444_texture_format, | |
69 id_allocation_chunk_size, | |
70 use_distance_field_text); | |
71 if (!resource_provider) | |
72 return; | |
73 | |
74 LayerTreeSettings settings; | |
75 if (output_surface->context_provider()) { | |
76 TextureMailboxDeleter* texture_mailbox_deleter = NULL; | |
77 scoped_ptr<GLRenderer> renderer = | |
78 GLRenderer::Create(this, | |
79 &settings, | |
80 output_surface.get(), | |
81 resource_provider.get(), | |
82 texture_mailbox_deleter, | |
83 highp_threshold_min); | |
84 if (!renderer) | |
85 return; | |
86 renderer_ = renderer.Pass(); | |
87 } else { | |
88 scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( | |
89 this, &settings, output_surface.get(), resource_provider.get()); | |
90 if (!renderer) | |
91 return; | |
92 renderer_ = renderer.Pass(); | |
93 } | |
94 | |
95 output_surface_ = output_surface.Pass(); | |
96 resource_provider_ = resource_provider.Pass(); | |
97 child_id_ = resource_provider_->CreateChild( | |
98 base::Bind(&Display::ReturnResources, base::Unretained(this))); | |
99 } | |
100 | |
38 bool Display::Draw() { | 101 bool Display::Draw() { |
39 if (!current_surface_) | 102 if (!current_surface_) |
40 return false; | 103 return false; |
41 | 104 |
105 InitializeOutputSurface(); | |
106 if (!output_surface_) | |
107 return false; | |
108 | |
42 // TODO(jamesr): Use the surface aggregator instead. | 109 // TODO(jamesr): Use the surface aggregator instead. |
43 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); | 110 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); |
44 CompositorFrame* current_frame = current_surface_->GetEligibleFrame(); | 111 CompositorFrame* current_frame = current_surface_->GetEligibleFrame(); |
45 frame_data->resource_list = | 112 frame_data->resource_list = |
46 current_frame->delegated_frame_data->resource_list; | 113 current_frame->delegated_frame_data->resource_list; |
47 RenderPass::CopyAll(current_frame->delegated_frame_data->render_pass_list, | 114 RenderPass::CopyAll(current_frame->delegated_frame_data->render_pass_list, |
48 &frame_data->render_pass_list); | 115 &frame_data->render_pass_list); |
49 | 116 |
50 if (!layer_tree_host_) { | 117 if (frame_data->render_pass_list.empty()) |
51 // TODO(jbauman): Switch to use ResourceProvider and GLRenderer directly, | 118 return false; |
52 // as using LayerTreeHost from here is a layering violation. | 119 |
53 LayerTreeSettings settings; | 120 const ResourceProvider::ResourceIdMap& resource_map = |
54 layer_tree_host_ = LayerTreeHost::CreateSingleThreaded( | 121 resource_provider_->GetChildToParentMap(child_id_); |
55 this, this, bitmap_manager_, settings); | 122 resource_provider_->ReceiveFromChild(child_id_, frame_data->resource_list); |
56 resource_collection_ = new DelegatedFrameResourceCollection; | 123 |
57 resource_collection_->SetClient(this); | 124 bool invalid_frame = false; |
58 layer_tree_host_->SetLayerTreeHostClientReady(); | 125 ResourceProvider::ResourceIdArray resources_in_frame; |
126 DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback = | |
127 base::Bind(&ResourceRemapHelper, | |
128 &invalid_frame, | |
129 resource_map, | |
130 &resources_in_frame); | |
131 for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) { | |
132 RenderPass* pass = frame_data->render_pass_list[i]; | |
133 for (size_t j = 0; j < pass->quad_list.size(); ++j) { | |
134 DrawQuad* quad = pass->quad_list[j]; | |
135 quad->IterateResources(remap_resources_to_parent_callback); | |
136 } | |
59 } | 137 } |
60 if (!delegated_frame_provider_ || | |
61 delegated_frame_provider_->frame_size() != | |
62 frame_data->render_pass_list.back()->output_rect.size()) { | |
63 delegated_frame_provider_ = | |
64 new DelegatedFrameProvider(resource_collection_, frame_data.Pass()); | |
65 delegated_layer_ = | |
66 DelegatedRendererLayer::Create(delegated_frame_provider_); | |
67 | 138 |
68 layer_tree_host_->SetRootLayer(delegated_layer_); | 139 if (invalid_frame) |
69 delegated_layer_->SetDisplaySize(current_surface_->size()); | 140 return false; |
70 delegated_layer_->SetBounds(current_surface_->size()); | 141 resource_provider_->DeclareUsedResourcesFromChild(child_id_, |
71 delegated_layer_->SetContentsOpaque(true); | 142 resources_in_frame); |
72 delegated_layer_->SetIsDrawable(true); | |
73 } else { | |
74 delegated_frame_provider_->SetFrameData(frame_data.Pass()); | |
75 } | |
76 layer_tree_host_->SetViewportSize(current_surface_->size()); | |
77 | 143 |
144 float device_scale_factor = 1.0f; | |
145 gfx::Rect device_viewport_rect = gfx::Rect(current_surface_->size()); | |
146 gfx::Rect device_clip_rect = device_viewport_rect; | |
147 bool disable_picture_quad_image_filtering = false; | |
148 | |
149 renderer_->DrawFrame(&frame_data->render_pass_list, | |
150 device_scale_factor, | |
151 device_viewport_rect, | |
152 device_clip_rect, | |
153 disable_picture_quad_image_filtering); | |
154 CompositorFrameMetadata metadata; | |
155 renderer_->SwapBuffers(metadata); | |
78 return true; | 156 return true; |
79 } | 157 } |
80 | 158 |
81 scoped_ptr<OutputSurface> Display::CreateOutputSurface(bool fallback) { | |
82 return client_->CreateOutputSurface(); | |
83 } | |
84 | |
85 void Display::ScheduleComposite() { | |
86 if (scheduled_draw_) | |
87 return; | |
88 | |
89 scheduled_draw_ = true; | |
90 | |
91 base::MessageLoop::current()->PostTask( | |
92 FROM_HERE, | |
93 base::Bind(&Display::DoComposite, schedule_draw_factory_.GetWeakPtr())); | |
94 } | |
95 | |
96 void Display::ScheduleAnimation() { | |
97 ScheduleComposite(); | |
98 } | |
99 | |
100 void Display::DoComposite() { | |
101 scheduled_draw_ = false; | |
102 layer_tree_host_->Composite(gfx::FrameTime::Now()); | |
103 } | |
104 | |
105 int Display::CurrentSurfaceID() { | 159 int Display::CurrentSurfaceID() { |
106 return current_surface_ ? current_surface_->surface_id() : 0; | 160 return current_surface_ ? current_surface_->surface_id() : 0; |
107 } | 161 } |
108 | 162 |
109 void Display::ReturnResources(const ReturnedResourceArray& resources) { | 163 void Display::ReturnResources(const ReturnedResourceArray& resources) { |
110 // We never generate any resources, so we should never have any returned. | |
111 DCHECK(resources.empty()); | |
112 } | 164 } |
113 | 165 |
114 } // namespace cc | 166 } // namespace cc |
115 | 167 |
116 #endif // CC_SURFACES_DISPLAY_H_ | 168 #endif // CC_SURFACES_DISPLAY_H_ |
OLD | NEW |