Chromium Code Reviews| Index: content/browser/android/ui_resource_provider_impl.cc |
| diff --git a/content/browser/android/ui_resource_provider_impl.cc b/content/browser/android/ui_resource_provider_impl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..712febbe64491b4f9987d50f7f91dc321a4e2164 |
| --- /dev/null |
| +++ b/content/browser/android/ui_resource_provider_impl.cc |
| @@ -0,0 +1,187 @@ |
| +// Copyright 2013 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 "content/browser/android/ui_resource_provider_impl.h" |
| + |
| +#include "cc/resources/scoped_ui_resource.h" |
| +#include "cc/resources/ui_resource_bitmap.h" |
| +#include "cc/resources/ui_resource_client.h" |
| +#include "content/public/browser/android/ui_resource_listener.h" |
| +#include "skia/ext/refptr.h" |
| +#include "third_party/skia/include/core/SkBitmap.h" |
| +#include "third_party/skia/include/core/SkCanvas.h" |
| +#include "third_party/skia/include/core/SkMallocPixelRef.h" |
| + |
| +namespace { |
| + |
| +class TransientUIResource : public cc::ScopedUIResource { |
| + public: |
| + static scoped_ptr<TransientUIResource> Create( |
| + cc::LayerTreeHost* host, |
| + const cc::UIResourceBitmap& bitmap) { |
| + return make_scoped_ptr(new TransientUIResource(host, bitmap)); |
| + } |
| + |
| + virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid, |
| + bool resource_lost) OVERRIDE { |
| + if (!retrieved_) { |
|
David Trainor- moved to gerrit
2014/05/13 20:38:00
This feels a bit fragile. So we're returning the
powei
2014/05/13 23:38:03
GetBitmap is called (again) only when the context
David Trainor- moved to gerrit
2014/05/16 18:18:35
I guess I just think that's a scary assumption unl
|
| + cc::UIResourceBitmap old_bitmap(bitmap_); |
| + |
| + // Return a place holder for all following calls to GetBitmap. |
| + SkBitmap tiny_bitmap; |
| + SkCanvas canvas(tiny_bitmap); |
| + tiny_bitmap.setConfig( |
| + SkBitmap::kARGB_8888_Config, 1, 1, 0, kOpaque_SkAlphaType); |
| + tiny_bitmap.allocPixels(); |
| + canvas.drawColor(SK_ColorWHITE); |
| + tiny_bitmap.setImmutable(); |
| + |
| + // Release our reference of the true bitmap. |
| + bitmap_ = cc::UIResourceBitmap(tiny_bitmap); |
| + |
| + retrieved_ = true; |
| + return old_bitmap; |
| + } |
| + return bitmap_; |
|
David Trainor- moved to gerrit
2014/05/13 20:38:00
return ScopedUIResource::GetBitmap(...)?
powei
2014/05/13 23:38:03
Done.
|
| + } |
| + |
| + protected: |
| + TransientUIResource(cc::LayerTreeHost* host, |
| + const cc::UIResourceBitmap& bitmap) |
| + : cc::ScopedUIResource(host, bitmap), retrieved_(false) {} |
| + |
| + private: |
| + bool retrieved_; |
|
David Trainor- moved to gerrit
2014/05/13 20:38:00
Do we need DISALLOW_COPY_AND_ASSIGN?
powei
2014/05/13 23:38:03
Done.
|
| +}; |
| + |
| +} // anonymous namespace |
| + |
| +namespace content { |
| + |
| +UIResourceProviderImpl::UIResourceProviderImpl() : host_(NULL) { |
| +} |
| + |
| +UIResourceProviderImpl::~UIResourceProviderImpl() { |
| + // The lifetime of the UI resource provider should be greater than all of the |
| + // listeners. |
| + DCHECK_EQ(listeners_.size(), 0u); |
| +} |
| + |
| +void UIResourceProviderImpl::SetLayerTreeHost(cc::LayerTreeHost* host) { |
| + if (host_ == host) |
| + return; |
| + |
| + ui_resource_map_.clear(); |
| + |
| + UIResourcesAreInvalid(); |
| + host_ = host; |
| + |
| + if (host_) |
| + RecreateUIResources(); |
| +} |
| + |
| +void UIResourceProviderImpl::AddListener(UIResourceListener* listener) { |
| + UIResourceListenerList::iterator iter = |
| + std::find(listeners_.begin(), listeners_.end(), listener); |
| + if (iter == listeners_.end()) |
| + listeners_.push_back(listener); |
| +} |
| + |
| +void UIResourceProviderImpl::RemoveListener(UIResourceListener* listener) { |
| + UIResourceListenerList::iterator iter = |
| + std::find(listeners_.begin(), listeners_.end(), listener); |
| + if (iter != listeners_.end()) |
| + listeners_.erase(iter); |
| +} |
| + |
| +void UIResourceProviderImpl::UIResourcesAreInvalid() { |
| + for (UIResourceListenerList::iterator iter = listeners_.begin(); |
| + iter != listeners_.end(); |
| + iter++) { |
| + (*iter)->OnUIResourcesAreInvalid(); |
| + } |
| +} |
| + |
| +void UIResourceProviderImpl::RecreateUIResources() { |
| + for (UIResourceListenerList::iterator iter = listeners_.begin(); |
| + iter != listeners_.end(); |
| + iter++) { |
| + (*iter)->OnRecreateUIResources(); |
| + } |
| +} |
| + |
| +cc::UIResourceId UIResourceProviderImpl::GenerateUIResourceFromUIResourceBitmap( |
| + const cc::UIResourceBitmap& bitmap, |
| + bool is_transient) { |
| + if (!host_) |
| + return 0; |
| + |
| + cc::UIResourceId id = 0; |
| + scoped_ptr<cc::UIResourceClient> resource; |
| + if (is_transient) { |
| + scoped_ptr<TransientUIResource> transient_resource = |
| + TransientUIResource::Create(host_, bitmap); |
| + id = transient_resource->id(); |
| + resource = transient_resource.Pass(); |
| + } else { |
| + scoped_ptr<cc::ScopedUIResource> scoped_resource = |
| + cc::ScopedUIResource::Create(host_, bitmap); |
| + id = scoped_resource->id(); |
| + resource = scoped_resource.Pass(); |
| + } |
| + |
| + ui_resource_map_.set(id, resource.Pass()); |
| + |
| + return id; |
| +} |
| + |
| +cc::UIResourceId UIResourceProviderImpl::GenerateUIResource( |
| + const SkBitmap& bitmap, |
| + bool is_transient) { |
| + return GenerateUIResourceFromUIResourceBitmap(cc::UIResourceBitmap(bitmap), |
| + is_transient); |
| +} |
| + |
| +cc::UIResourceId UIResourceProviderImpl::GenerateCompressedUIResource( |
| + const gfx::Size& size, |
| + void* pixels, |
| + bool is_transient) { |
| + DCHECK_LT(0, size.width()); |
| + DCHECK_LT(0, size.height()); |
| + DCHECK_EQ(0, size.width() % 4); |
| + DCHECK_EQ(0, size.height() % 4); |
| + |
| + size_t data_size = size.width() * size.height() / 2; |
| + SkImageInfo info = {size.width(), |
| + size.height() / 2, |
| + kAlpha_8_SkColorType, |
| + kPremul_SkAlphaType}; |
| + skia::RefPtr<SkMallocPixelRef> etc1_pixel_ref = |
| + skia::AdoptRef(SkMallocPixelRef::NewAllocate(info, 0, 0)); |
| + memcpy(etc1_pixel_ref->getAddr(), pixels, data_size); |
| + etc1_pixel_ref->setImmutable(); |
| + return GenerateUIResourceFromUIResourceBitmap( |
| + cc::UIResourceBitmap(etc1_pixel_ref, size), is_transient); |
| +} |
| + |
| +cc::UIResourceId UIResourceProviderImpl::GenerateCompressedUIResource( |
| + const skia::RefPtr<SkPixelRef>& pixel_ref, |
| + bool is_transient) { |
| + gfx::Size size(pixel_ref->info().width(), pixel_ref->info().height()); |
| + DCHECK_LT(0, size.width()); |
| + DCHECK_LT(0, size.height()); |
| + DCHECK_EQ(0, size.width() % 4); |
| + DCHECK_EQ(0, size.height() % 4); |
| + |
| + return GenerateUIResourceFromUIResourceBitmap( |
| + cc::UIResourceBitmap(pixel_ref, size), is_transient); |
| +} |
| + |
| +void UIResourceProviderImpl::DeleteUIResource(cc::UIResourceId resource_id) { |
| + UIResourceMap::iterator iter = ui_resource_map_.find(resource_id); |
| + if (iter != ui_resource_map_.end()) |
| + ui_resource_map_.erase(iter); |
| +} |
| + |
| +} // namespace content |