| OLD | NEW |
| (Empty) | |
| 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 "content/browser/android/ui_resource_provider_impl.h" |
| 6 |
| 7 #include "cc/resources/scoped_ui_resource.h" |
| 8 #include "cc/resources/ui_resource_bitmap.h" |
| 9 #include "cc/resources/ui_resource_client.h" |
| 10 #include "content/public/browser/android/ui_resource_listener.h" |
| 11 #include "skia/ext/refptr.h" |
| 12 #include "third_party/skia/include/core/SkBitmap.h" |
| 13 #include "third_party/skia/include/core/SkCanvas.h" |
| 14 #include "third_party/skia/include/core/SkMallocPixelRef.h" |
| 15 |
| 16 namespace { |
| 17 |
| 18 class TransientUIResource : public cc::ScopedUIResource { |
| 19 public: |
| 20 static scoped_ptr<TransientUIResource> Create( |
| 21 cc::LayerTreeHost* host, |
| 22 const cc::UIResourceBitmap& bitmap) { |
| 23 return make_scoped_ptr(new TransientUIResource(host, bitmap)); |
| 24 } |
| 25 |
| 26 virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid, |
| 27 bool resource_lost) OVERRIDE { |
| 28 if (!retrieved_) { |
| 29 cc::UIResourceBitmap old_bitmap(bitmap_); |
| 30 |
| 31 // Return a place holder for all following calls to GetBitmap. |
| 32 SkBitmap tiny_bitmap; |
| 33 SkCanvas canvas(tiny_bitmap); |
| 34 tiny_bitmap.setConfig( |
| 35 SkBitmap::kARGB_8888_Config, 1, 1, 0, kOpaque_SkAlphaType); |
| 36 tiny_bitmap.allocPixels(); |
| 37 canvas.drawColor(SK_ColorWHITE); |
| 38 tiny_bitmap.setImmutable(); |
| 39 |
| 40 // Release our reference of the true bitmap. |
| 41 bitmap_ = cc::UIResourceBitmap(tiny_bitmap); |
| 42 |
| 43 retrieved_ = true; |
| 44 return old_bitmap; |
| 45 } |
| 46 return ScopedUIResource::GetBitmap(uid, resource_lost); |
| 47 } |
| 48 |
| 49 protected: |
| 50 TransientUIResource(cc::LayerTreeHost* host, |
| 51 const cc::UIResourceBitmap& bitmap) |
| 52 : cc::ScopedUIResource(host, bitmap), retrieved_(false) {} |
| 53 |
| 54 private: |
| 55 bool retrieved_; |
| 56 |
| 57 DISALLOW_COPY_AND_ASSIGN(TransientUIResource); |
| 58 }; |
| 59 |
| 60 } // anonymous namespace |
| 61 |
| 62 namespace content { |
| 63 |
| 64 UIResourceProviderImpl::UIResourceProviderImpl() : host_(NULL) { |
| 65 } |
| 66 |
| 67 UIResourceProviderImpl::~UIResourceProviderImpl() { |
| 68 // The lifetime of the UI resource provider should be greater than all of the |
| 69 // listeners. |
| 70 DCHECK_EQ(listeners_.size(), 0u); |
| 71 } |
| 72 |
| 73 void UIResourceProviderImpl::SetLayerTreeHost(cc::LayerTreeHost* host) { |
| 74 if (host_ == host) |
| 75 return; |
| 76 |
| 77 ui_resource_map_.clear(); |
| 78 |
| 79 UIResourcesAreInvalid(); |
| 80 host_ = host; |
| 81 |
| 82 if (host_) |
| 83 RecreateUIResources(); |
| 84 } |
| 85 |
| 86 void UIResourceProviderImpl::AddListener(UIResourceListener* listener) { |
| 87 UIResourceListenerList::iterator iter = |
| 88 std::find(listeners_.begin(), listeners_.end(), listener); |
| 89 if (iter == listeners_.end()) |
| 90 listeners_.push_back(listener); |
| 91 } |
| 92 |
| 93 void UIResourceProviderImpl::RemoveListener(UIResourceListener* listener) { |
| 94 UIResourceListenerList::iterator iter = |
| 95 std::find(listeners_.begin(), listeners_.end(), listener); |
| 96 if (iter != listeners_.end()) |
| 97 listeners_.erase(iter); |
| 98 } |
| 99 |
| 100 void UIResourceProviderImpl::UIResourcesAreInvalid() { |
| 101 for (UIResourceListenerList::iterator iter = listeners_.begin(); |
| 102 iter != listeners_.end(); |
| 103 iter++) { |
| 104 (*iter)->OnUIResourcesAreInvalid(); |
| 105 } |
| 106 } |
| 107 |
| 108 void UIResourceProviderImpl::RecreateUIResources() { |
| 109 for (UIResourceListenerList::iterator iter = listeners_.begin(); |
| 110 iter != listeners_.end(); |
| 111 iter++) { |
| 112 (*iter)->OnRecreateUIResources(); |
| 113 } |
| 114 } |
| 115 |
| 116 cc::UIResourceId UIResourceProviderImpl::GenerateUIResourceFromUIResourceBitmap( |
| 117 const cc::UIResourceBitmap& bitmap, |
| 118 bool is_transient) { |
| 119 if (!host_) |
| 120 return 0; |
| 121 |
| 122 cc::UIResourceId id = 0; |
| 123 scoped_ptr<cc::UIResourceClient> resource; |
| 124 if (is_transient) { |
| 125 scoped_ptr<TransientUIResource> transient_resource = |
| 126 TransientUIResource::Create(host_, bitmap); |
| 127 id = transient_resource->id(); |
| 128 resource = transient_resource.Pass(); |
| 129 } else { |
| 130 scoped_ptr<cc::ScopedUIResource> scoped_resource = |
| 131 cc::ScopedUIResource::Create(host_, bitmap); |
| 132 id = scoped_resource->id(); |
| 133 resource = scoped_resource.Pass(); |
| 134 } |
| 135 |
| 136 ui_resource_map_.set(id, resource.Pass()); |
| 137 |
| 138 return id; |
| 139 } |
| 140 |
| 141 cc::UIResourceId UIResourceProviderImpl::GenerateUIResource( |
| 142 const SkBitmap& bitmap, |
| 143 bool is_transient) { |
| 144 return GenerateUIResourceFromUIResourceBitmap(cc::UIResourceBitmap(bitmap), |
| 145 is_transient); |
| 146 } |
| 147 |
| 148 cc::UIResourceId UIResourceProviderImpl::GenerateCompressedUIResource( |
| 149 const gfx::Size& size, |
| 150 void* pixels, |
| 151 bool is_transient) { |
| 152 DCHECK_LT(0, size.width()); |
| 153 DCHECK_LT(0, size.height()); |
| 154 DCHECK_EQ(0, size.width() % 4); |
| 155 DCHECK_EQ(0, size.height() % 4); |
| 156 |
| 157 size_t data_size = size.width() * size.height() / 2; |
| 158 SkImageInfo info = {size.width(), |
| 159 size.height() / 2, |
| 160 kAlpha_8_SkColorType, |
| 161 kPremul_SkAlphaType}; |
| 162 skia::RefPtr<SkMallocPixelRef> etc1_pixel_ref = |
| 163 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info, 0, 0)); |
| 164 memcpy(etc1_pixel_ref->getAddr(), pixels, data_size); |
| 165 etc1_pixel_ref->setImmutable(); |
| 166 return GenerateUIResourceFromUIResourceBitmap( |
| 167 cc::UIResourceBitmap(etc1_pixel_ref, size), is_transient); |
| 168 } |
| 169 |
| 170 cc::UIResourceId UIResourceProviderImpl::GenerateCompressedUIResource( |
| 171 const skia::RefPtr<SkPixelRef>& pixel_ref, |
| 172 bool is_transient) { |
| 173 gfx::Size size(pixel_ref->info().width(), pixel_ref->info().height()); |
| 174 DCHECK_LT(0, size.width()); |
| 175 DCHECK_LT(0, size.height()); |
| 176 DCHECK_EQ(0, size.width() % 4); |
| 177 DCHECK_EQ(0, size.height() % 4); |
| 178 |
| 179 return GenerateUIResourceFromUIResourceBitmap( |
| 180 cc::UIResourceBitmap(pixel_ref, size), is_transient); |
| 181 } |
| 182 |
| 183 void UIResourceProviderImpl::DeleteUIResource(cc::UIResourceId resource_id) { |
| 184 UIResourceMap::iterator iter = ui_resource_map_.find(resource_id); |
| 185 if (iter != ui_resource_map_.end()) |
| 186 ui_resource_map_.erase(iter); |
| 187 } |
| 188 |
| 189 } // namespace content |
| OLD | NEW |