summaryrefslogtreecommitdiffstats
path: root/chromium/cc/layers/image_layer.cc
blob: cada84df3ccb4a0ce63731db532f2e0cd1f08358 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2010 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/layers/image_layer.h"

#include "base/compiler_specific.h"
#include "cc/resources/image_layer_updater.h"
#include "cc/resources/layer_updater.h"
#include "cc/resources/prioritized_resource.h"
#include "cc/resources/resource_update_queue.h"
#include "cc/trees/layer_tree_host.h"

namespace cc {

scoped_refptr<ImageLayer> ImageLayer::Create() {
  return make_scoped_refptr(new ImageLayer());
}

ImageLayer::ImageLayer() : TiledLayer() {}

ImageLayer::~ImageLayer() {}

void ImageLayer::SetBitmap(const SkBitmap& bitmap) {
  // SetBitmap() currently gets called whenever there is any
  // style change that affects the layer even if that change doesn't
  // affect the actual contents of the image (e.g. a CSS animation).
  // With this check in place we avoid unecessary texture uploads.
  if (bitmap.pixelRef() && bitmap.pixelRef() == bitmap_.pixelRef())
    return;

  bitmap_ = bitmap;
  SetNeedsDisplay();
}

void ImageLayer::SetTexturePriorities(const PriorityCalculator& priority_calc) {
  // Update the tile data before creating all the layer's tiles.
  UpdateTileSizeAndTilingOption();

  TiledLayer::SetTexturePriorities(priority_calc);
}

bool ImageLayer::Update(ResourceUpdateQueue* queue,
                        const OcclusionTracker<Layer>* occlusion) {
  CreateUpdaterIfNeeded();
  if (!updater_->UsingBitmap(bitmap_)) {
    updater_->SetBitmap(bitmap_);
    UpdateTileSizeAndTilingOption();
    InvalidateContentRect(gfx::Rect(content_bounds()));
  }
  return TiledLayer::Update(queue, occlusion);
}

void ImageLayer::CreateUpdaterIfNeeded() {
  if (updater_.get())
    return;

  updater_ = ImageLayerUpdater::Create();
  SetTextureFormat(
      layer_tree_host()->GetRendererCapabilities().best_texture_format);
}

LayerUpdater* ImageLayer::Updater() const {
  return updater_.get();
}

void ImageLayer::CalculateContentsScale(float ideal_contents_scale,
                                        float device_scale_factor,
                                        float page_scale_factor,
                                        float maximum_animation_contents_scale,
                                        bool animating_transform_to_screen,
                                        float* contents_scale_x,
                                        float* contents_scale_y,
                                        gfx::Size* content_bounds) {
  *contents_scale_x = ImageContentsScaleX();
  *contents_scale_y = ImageContentsScaleY();
  *content_bounds = gfx::Size(bitmap_.width(), bitmap_.height());
}

bool ImageLayer::DrawsContent() const {
  return !bitmap_.isNull() && TiledLayer::DrawsContent();
}

void ImageLayer::OnOutputSurfaceCreated() {
  SetTextureFormat(
      layer_tree_host()->GetRendererCapabilities().best_texture_format);
  TiledLayer::OnOutputSurfaceCreated();
}

float ImageLayer::ImageContentsScaleX() const {
  if (bounds().IsEmpty() || bitmap_.width() == 0)
    return 1;
  return static_cast<float>(bitmap_.width()) / bounds().width();
}

float ImageLayer::ImageContentsScaleY() const {
  if (bounds().IsEmpty() || bitmap_.height() == 0)
    return 1;
  return static_cast<float>(bitmap_.height()) / bounds().height();
}

}  // namespace cc