| 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 |