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