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/message_loop/message_loop.h" 8 #include "cc/output/compositor_frame.h" 9 #include "cc/output/direct_renderer.h" 10 #include "cc/output/gl_renderer.h" 11 #include "cc/output/software_renderer.h" 12 #include "cc/surfaces/display_client.h" 13 #include "cc/surfaces/surface.h" 14 15 namespace cc { 16 17 static ResourceProvider::ResourceId ResourceRemapHelper( 18 bool* invalid_frame, 19 const ResourceProvider::ResourceIdMap& child_to_parent_map, 20 ResourceProvider::ResourceIdArray* resources_in_frame, 21 ResourceProvider::ResourceId id) { 22 ResourceProvider::ResourceIdMap::const_iterator it = 23 child_to_parent_map.find(id); 24 if (it == child_to_parent_map.end()) { 25 *invalid_frame = true; 26 return 0; 27 } 28 29 DCHECK_EQ(it->first, id); 30 ResourceProvider::ResourceId remapped_id = it->second; 31 resources_in_frame->push_back(id); 32 return remapped_id; 33 } 34 35 Display::Display(DisplayClient* client, 36 SurfaceManager* manager, 37 SharedBitmapManager* bitmap_manager) 38 : client_(client), 39 manager_(manager), 40 aggregator_(manager), 41 bitmap_manager_(bitmap_manager) { 42 } 43 44 Display::~Display() { 45 } 46 47 void Display::Resize(const gfx::Size& size) { 48 current_surface_.reset(new Surface(manager_, this, size)); 49 } 50 51 void Display::InitializeOutputSurface() { 52 if (output_surface_) 53 return; 54 scoped_ptr<OutputSurface> output_surface = client_->CreateOutputSurface(); 55 if (!output_surface->BindToClient(this)) 56 return; 57 58 int highp_threshold_min = 0; 59 bool use_rgba_4444_texture_format = false; 60 size_t id_allocation_chunk_size = 1; 61 bool use_distance_field_text = false; 62 scoped_ptr<ResourceProvider> resource_provider = 63 ResourceProvider::Create(output_surface.get(), 64 bitmap_manager_, 65 highp_threshold_min, 66 use_rgba_4444_texture_format, 67 id_allocation_chunk_size, 68 use_distance_field_text); 69 if (!resource_provider) 70 return; 71 72 if (output_surface->context_provider()) { 73 TextureMailboxDeleter* texture_mailbox_deleter = NULL; 74 scoped_ptr<GLRenderer> renderer = 75 GLRenderer::Create(this, 76 &settings_, 77 output_surface.get(), 78 resource_provider.get(), 79 texture_mailbox_deleter, 80 highp_threshold_min); 81 if (!renderer) 82 return; 83 renderer_ = renderer.Pass(); 84 } else { 85 scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( 86 this, &settings_, output_surface.get(), resource_provider.get()); 87 if (!renderer) 88 return; 89 renderer_ = renderer.Pass(); 90 } 91 92 output_surface_ = output_surface.Pass(); 93 resource_provider_ = resource_provider.Pass(); 94 child_id_ = resource_provider_->CreateChild( 95 base::Bind(&Display::ReturnResources, base::Unretained(this))); 96 } 97 98 bool Display::Draw() { 99 if (!current_surface_) 100 return false; 101 102 InitializeOutputSurface(); 103 if (!output_surface_) 104 return false; 105 106 // TODO(jamesr): Use the surface aggregator instead. 107 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); 108 CompositorFrame* current_frame = current_surface_->GetEligibleFrame(); 109 frame_data->resource_list = 110 current_frame->delegated_frame_data->resource_list; 111 RenderPass::CopyAll(current_frame->delegated_frame_data->render_pass_list, 112 &frame_data->render_pass_list); 113 114 if (frame_data->render_pass_list.empty()) 115 return false; 116 117 const ResourceProvider::ResourceIdMap& resource_map = 118 resource_provider_->GetChildToParentMap(child_id_); 119 resource_provider_->ReceiveFromChild(child_id_, frame_data->resource_list); 120 121 bool invalid_frame = false; 122 ResourceProvider::ResourceIdArray resources_in_frame; 123 DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback = 124 base::Bind(&ResourceRemapHelper, 125 &invalid_frame, 126 resource_map, 127 &resources_in_frame); 128 for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) { 129 RenderPass* pass = frame_data->render_pass_list[i]; 130 for (size_t j = 0; j < pass->quad_list.size(); ++j) { 131 DrawQuad* quad = pass->quad_list[j]; 132 quad->IterateResources(remap_resources_to_parent_callback); 133 } 134 } 135 136 if (invalid_frame) 137 return false; 138 resource_provider_->DeclareUsedResourcesFromChild(child_id_, 139 resources_in_frame); 140 141 float device_scale_factor = 1.0f; 142 gfx::Rect device_viewport_rect = gfx::Rect(current_surface_->size()); 143 gfx::Rect device_clip_rect = device_viewport_rect; 144 bool disable_picture_quad_image_filtering = false; 145 146 renderer_->DrawFrame(&frame_data->render_pass_list, 147 device_scale_factor, 148 device_viewport_rect, 149 device_clip_rect, 150 disable_picture_quad_image_filtering); 151 CompositorFrameMetadata metadata; 152 renderer_->SwapBuffers(metadata); 153 return true; 154 } 155 156 SurfaceId Display::CurrentSurfaceId() { 157 return current_surface_ ? current_surface_->surface_id() : SurfaceId(); 158 } 159 160 void Display::ReturnResources(const ReturnedResourceArray& resources) { 161 } 162 163 } // namespace cc 164