Home | History | Annotate | Download | only in layers
      1 // Copyright 2010 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/layers/content_layer.h"
      6 
      7 #include "base/auto_reset.h"
      8 #include "base/metrics/histogram.h"
      9 #include "base/time/time.h"
     10 #include "cc/layers/content_layer_client.h"
     11 #include "cc/resources/bitmap_content_layer_updater.h"
     12 #include "cc/resources/bitmap_skpicture_content_layer_updater.h"
     13 #include "cc/resources/layer_painter.h"
     14 #include "cc/trees/layer_tree_host.h"
     15 #include "third_party/skia/include/core/SkPictureRecorder.h"
     16 
     17 namespace cc {
     18 
     19 ContentLayerPainter::ContentLayerPainter(ContentLayerClient* client)
     20     : client_(client) {}
     21 
     22 scoped_ptr<ContentLayerPainter> ContentLayerPainter::Create(
     23     ContentLayerClient* client) {
     24   return make_scoped_ptr(new ContentLayerPainter(client));
     25 }
     26 
     27 void ContentLayerPainter::Paint(SkCanvas* canvas,
     28                                 const gfx::Rect& content_rect,
     29                                 gfx::RectF* opaque) {
     30   client_->PaintContents(canvas,
     31                          content_rect,
     32                          opaque,
     33                          ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
     34 }
     35 
     36 scoped_refptr<ContentLayer> ContentLayer::Create(ContentLayerClient* client) {
     37   return make_scoped_refptr(new ContentLayer(client));
     38 }
     39 
     40 ContentLayer::ContentLayer(ContentLayerClient* client)
     41     : TiledLayer(),
     42       client_(client),
     43       can_use_lcd_text_last_frame_(can_use_lcd_text()) {
     44 }
     45 
     46 ContentLayer::~ContentLayer() {}
     47 
     48 bool ContentLayer::DrawsContent() const {
     49   return TiledLayer::DrawsContent() && client_;
     50 }
     51 
     52 void ContentLayer::SetLayerTreeHost(LayerTreeHost* host) {
     53   TiledLayer::SetLayerTreeHost(host);
     54 
     55   if (!updater_.get())
     56     return;
     57 
     58   if (host) {
     59     updater_->set_rendering_stats_instrumentation(
     60         host->rendering_stats_instrumentation());
     61   } else {
     62     updater_->set_rendering_stats_instrumentation(NULL);
     63   }
     64 }
     65 
     66 void ContentLayer::SetTexturePriorities(
     67     const PriorityCalculator& priority_calc) {
     68   // Update the tile data before creating all the layer's tiles.
     69   UpdateTileSizeAndTilingOption();
     70 
     71   TiledLayer::SetTexturePriorities(priority_calc);
     72 }
     73 
     74 bool ContentLayer::Update(ResourceUpdateQueue* queue,
     75                           const OcclusionTracker<Layer>* occlusion) {
     76   {
     77     base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
     78                                                   true);
     79 
     80     CreateUpdaterIfNeeded();
     81     UpdateCanUseLCDText();
     82   }
     83 
     84   bool updated = TiledLayer::Update(queue, occlusion);
     85   return updated;
     86 }
     87 
     88 bool ContentLayer::NeedMoreUpdates() {
     89   return NeedsIdlePaint();
     90 }
     91 
     92 LayerUpdater* ContentLayer::Updater() const {
     93   return updater_.get();
     94 }
     95 
     96 void ContentLayer::CreateUpdaterIfNeeded() {
     97   if (updater_.get())
     98     return;
     99   scoped_ptr<LayerPainter> painter =
    100       ContentLayerPainter::Create(client_).PassAs<LayerPainter>();
    101   if (layer_tree_host()->settings().per_tile_painting_enabled) {
    102     updater_ = BitmapSkPictureContentLayerUpdater::Create(
    103         painter.Pass(),
    104         rendering_stats_instrumentation(),
    105         id());
    106   } else {
    107     updater_ = BitmapContentLayerUpdater::Create(
    108         painter.Pass(),
    109         rendering_stats_instrumentation(),
    110         id());
    111   }
    112   updater_->SetOpaque(contents_opaque());
    113   if (client_)
    114     updater_->SetFillsBoundsCompletely(client_->FillsBoundsCompletely());
    115 
    116   SetTextureFormat(
    117       layer_tree_host()->GetRendererCapabilities().best_texture_format);
    118 }
    119 
    120 void ContentLayer::SetContentsOpaque(bool opaque) {
    121   Layer::SetContentsOpaque(opaque);
    122   if (updater_.get())
    123     updater_->SetOpaque(opaque);
    124 }
    125 
    126 void ContentLayer::UpdateCanUseLCDText() {
    127   if (can_use_lcd_text_last_frame_ == can_use_lcd_text())
    128     return;
    129 
    130   can_use_lcd_text_last_frame_ = can_use_lcd_text();
    131   if (client_)
    132     client_->DidChangeLayerCanUseLCDText();
    133 }
    134 
    135 bool ContentLayer::SupportsLCDText() const {
    136   return true;
    137 }
    138 
    139 skia::RefPtr<SkPicture> ContentLayer::GetPicture() const {
    140   if (!DrawsContent())
    141     return skia::RefPtr<SkPicture>();
    142 
    143   int width = bounds().width();
    144   int height = bounds().height();
    145   gfx::RectF opaque;
    146 
    147   SkPictureRecorder recorder;
    148   SkCanvas* canvas = recorder.beginRecording(width, height, NULL, 0);
    149   client_->PaintContents(canvas,
    150                          gfx::Rect(width, height),
    151                          &opaque,
    152                          ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
    153   skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
    154   return picture;
    155 }
    156 
    157 void ContentLayer::OnOutputSurfaceCreated() {
    158   SetTextureFormat(
    159       layer_tree_host()->GetRendererCapabilities().best_texture_format);
    160   TiledLayer::OnOutputSurfaceCreated();
    161 }
    162 
    163 }  // namespace cc
    164