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 "base/logging.h"
6#include "chrome/browser/android/thumbnail/thumbnail.h"
7#include "content/public/browser/android/ui_resource_provider.h"
8#include "third_party/skia/include/core/SkBitmap.h"
9#include "third_party/skia/include/core/SkCanvas.h"
10#include "ui/gfx/geometry/size_conversions.h"
11
12namespace {
13
14SkBitmap CreateSmallHolderBitmap() {
15  SkBitmap small_bitmap;
16  SkCanvas canvas(small_bitmap);
17  small_bitmap.allocPixels(
18      SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
19  canvas.drawColor(SK_ColorWHITE);
20  small_bitmap.setImmutable();
21  return small_bitmap;
22}
23
24}  // anonymous namespace
25
26scoped_ptr<Thumbnail> Thumbnail::Create(
27    TabId tab_id,
28    const base::Time& time_stamp,
29    float scale,
30    content::UIResourceProvider* ui_resource_provider,
31    ThumbnailDelegate* thumbnail_delegate) {
32  return make_scoped_ptr(new Thumbnail(
33      tab_id, time_stamp, scale, ui_resource_provider, thumbnail_delegate));
34}
35
36Thumbnail::Thumbnail(TabId tab_id,
37                     const base::Time& time_stamp,
38                     float scale,
39                     content::UIResourceProvider* ui_resource_provider,
40                     ThumbnailDelegate* thumbnail_delegate)
41    : tab_id_(tab_id),
42      time_stamp_(time_stamp),
43      scale_(scale),
44      bitmap_(gfx::Size(1, 1), true),
45      ui_resource_id_(0),
46      retrieved_(false),
47      ui_resource_provider_(ui_resource_provider),
48      thumbnail_delegate_(thumbnail_delegate) {
49}
50
51Thumbnail::~Thumbnail() {
52  ClearUIResourceId();
53}
54
55void Thumbnail::SetBitmap(const SkBitmap& bitmap) {
56  DCHECK(!bitmap.empty());
57  ClearUIResourceId();
58  scaled_content_size_ =
59      gfx::ScaleSize(gfx::Size(bitmap.width(), bitmap.height()), 1.f / scale_);
60  scaled_data_size_ = scaled_content_size_;
61  bitmap_ = cc::UIResourceBitmap(bitmap);
62}
63
64void Thumbnail::SetCompressedBitmap(skia::RefPtr<SkPixelRef> compressed_bitmap,
65                                    const gfx::Size& content_size) {
66  DCHECK(compressed_bitmap);
67  DCHECK(!content_size.IsEmpty());
68  ClearUIResourceId();
69  gfx::Size data_size(compressed_bitmap->info().width(),
70                      compressed_bitmap->info().height());
71  scaled_content_size_ = gfx::ScaleSize(content_size, 1.f / scale_);
72  scaled_data_size_ = gfx::ScaleSize(data_size, 1.f / scale_);
73  bitmap_ = cc::UIResourceBitmap(compressed_bitmap, data_size);
74}
75
76void Thumbnail::CreateUIResource() {
77  DCHECK(ui_resource_provider_);
78  if (!ui_resource_id_)
79    ui_resource_id_ = ui_resource_provider_->CreateUIResource(this);
80}
81
82cc::UIResourceBitmap Thumbnail::GetBitmap(cc::UIResourceId uid,
83                                          bool resource_lost) {
84  if (retrieved_)
85    return bitmap_;
86
87  retrieved_ = true;
88
89  cc::UIResourceBitmap old_bitmap(bitmap_);
90  // Return a place holder for all other calls to GetBitmap.
91  bitmap_ = cc::UIResourceBitmap(CreateSmallHolderBitmap());
92  return old_bitmap;
93}
94
95void Thumbnail::UIResourceIsInvalid() {
96  ui_resource_id_ = 0;
97  if (thumbnail_delegate_)
98    thumbnail_delegate_->InvalidateCachedThumbnail(this);
99}
100
101void Thumbnail::ClearUIResourceId() {
102  if (ui_resource_id_ && ui_resource_provider_)
103    ui_resource_provider_->DeleteUIResource(ui_resource_id_);
104  ui_resource_id_ = 0;
105}
106