Home | History | Annotate | Download | only in surfaces
      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