| 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..84dad9dee31c3169128021c1bb9a25a012c094c6
|
| --- /dev/null
|
| +++ b/content/browser/android/ui_resource_provider_impl.cc
|
| @@ -0,0 +1,189 @@
|
| +// Copyright 2014 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_) {
|
| + 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 ScopedUIResource::GetBitmap(uid, resource_lost);
|
| + }
|
| +
|
| + protected:
|
| + TransientUIResource(cc::LayerTreeHost* host,
|
| + const cc::UIResourceBitmap& bitmap)
|
| + : cc::ScopedUIResource(host, bitmap), retrieved_(false) {}
|
| +
|
| + private:
|
| + bool retrieved_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TransientUIResource);
|
| +};
|
| +
|
| +} // 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
|
|
|