diff options
Diffstat (limited to 'chromium/cc/surfaces/display.cc')
-rw-r--r-- | chromium/cc/surfaces/display.cc | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/chromium/cc/surfaces/display.cc b/chromium/cc/surfaces/display.cc new file mode 100644 index 00000000000..a39695f5732 --- /dev/null +++ b/chromium/cc/surfaces/display.cc @@ -0,0 +1,163 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/surfaces/display.h" + +#include "base/message_loop/message_loop.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/direct_renderer.h" +#include "cc/output/gl_renderer.h" +#include "cc/output/software_renderer.h" +#include "cc/surfaces/display_client.h" +#include "cc/surfaces/surface.h" + +namespace cc { + +static ResourceProvider::ResourceId ResourceRemapHelper( + bool* invalid_frame, + const ResourceProvider::ResourceIdMap& child_to_parent_map, + ResourceProvider::ResourceIdArray* resources_in_frame, + ResourceProvider::ResourceId id) { + ResourceProvider::ResourceIdMap::const_iterator it = + child_to_parent_map.find(id); + if (it == child_to_parent_map.end()) { + *invalid_frame = true; + return 0; + } + + DCHECK_EQ(it->first, id); + ResourceProvider::ResourceId remapped_id = it->second; + resources_in_frame->push_back(id); + return remapped_id; +} + +Display::Display(DisplayClient* client, + SurfaceManager* manager, + SharedBitmapManager* bitmap_manager) + : client_(client), + manager_(manager), + aggregator_(manager), + bitmap_manager_(bitmap_manager) { +} + +Display::~Display() { +} + +void Display::Resize(const gfx::Size& size) { + current_surface_.reset(new Surface(manager_, this, size)); +} + +void Display::InitializeOutputSurface() { + if (output_surface_) + return; + scoped_ptr<OutputSurface> output_surface = client_->CreateOutputSurface(); + if (!output_surface->BindToClient(this)) + return; + + int highp_threshold_min = 0; + bool use_rgba_4444_texture_format = false; + size_t id_allocation_chunk_size = 1; + bool use_distance_field_text = false; + scoped_ptr<ResourceProvider> resource_provider = + ResourceProvider::Create(output_surface.get(), + bitmap_manager_, + highp_threshold_min, + use_rgba_4444_texture_format, + id_allocation_chunk_size, + use_distance_field_text); + if (!resource_provider) + return; + + if (output_surface->context_provider()) { + TextureMailboxDeleter* texture_mailbox_deleter = NULL; + scoped_ptr<GLRenderer> renderer = + GLRenderer::Create(this, + &settings_, + output_surface.get(), + resource_provider.get(), + texture_mailbox_deleter, + highp_threshold_min); + if (!renderer) + return; + renderer_ = renderer.Pass(); + } else { + scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( + this, &settings_, output_surface.get(), resource_provider.get()); + if (!renderer) + return; + renderer_ = renderer.Pass(); + } + + output_surface_ = output_surface.Pass(); + resource_provider_ = resource_provider.Pass(); + child_id_ = resource_provider_->CreateChild( + base::Bind(&Display::ReturnResources, base::Unretained(this))); +} + +bool Display::Draw() { + if (!current_surface_) + return false; + + InitializeOutputSurface(); + if (!output_surface_) + return false; + + // TODO(jamesr): Use the surface aggregator instead. + scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + CompositorFrame* current_frame = current_surface_->GetEligibleFrame(); + frame_data->resource_list = + current_frame->delegated_frame_data->resource_list; + RenderPass::CopyAll(current_frame->delegated_frame_data->render_pass_list, + &frame_data->render_pass_list); + + if (frame_data->render_pass_list.empty()) + return false; + + const ResourceProvider::ResourceIdMap& resource_map = + resource_provider_->GetChildToParentMap(child_id_); + resource_provider_->ReceiveFromChild(child_id_, frame_data->resource_list); + + bool invalid_frame = false; + ResourceProvider::ResourceIdArray resources_in_frame; + DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback = + base::Bind(&ResourceRemapHelper, + &invalid_frame, + resource_map, + &resources_in_frame); + for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) { + RenderPass* pass = frame_data->render_pass_list[i]; + for (size_t j = 0; j < pass->quad_list.size(); ++j) { + DrawQuad* quad = pass->quad_list[j]; + quad->IterateResources(remap_resources_to_parent_callback); + } + } + + if (invalid_frame) + return false; + resource_provider_->DeclareUsedResourcesFromChild(child_id_, + resources_in_frame); + + float device_scale_factor = 1.0f; + gfx::Rect device_viewport_rect = gfx::Rect(current_surface_->size()); + gfx::Rect device_clip_rect = device_viewport_rect; + bool disable_picture_quad_image_filtering = false; + + renderer_->DrawFrame(&frame_data->render_pass_list, + device_scale_factor, + device_viewport_rect, + device_clip_rect, + disable_picture_quad_image_filtering); + CompositorFrameMetadata metadata; + renderer_->SwapBuffers(metadata); + return true; +} + +SurfaceId Display::CurrentSurfaceId() { + return current_surface_ ? current_surface_->surface_id() : SurfaceId(); +} + +void Display::ReturnResources(const ReturnedResourceArray& resources) { +} + +} // namespace cc |