// 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 "cc/blink/web_external_texture_layer_impl.h" #include "cc/blink/web_external_bitmap_impl.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/texture_layer.h" #include "cc/resources/resource_update_queue.h" #include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" #include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h" #include "third_party/WebKit/public/platform/WebExternalTextureMailbox.h" #include "third_party/WebKit/public/platform/WebFloatRect.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "third_party/WebKit/public/platform/WebSize.h" #include "third_party/khronos/GLES2/gl2.h" using cc::TextureLayer; using cc::ResourceUpdateQueue; namespace cc_blink { WebExternalTextureLayerImpl::WebExternalTextureLayerImpl( blink::WebExternalTextureLayerClient* client) : client_(client) { cc::TextureLayerClient* cc_client = client_ ? this : nullptr; scoped_refptr layer = TextureLayer::CreateForMailbox(cc_client); layer->SetIsDrawable(true); layer_.reset(new WebLayerImpl(layer)); } WebExternalTextureLayerImpl::~WebExternalTextureLayerImpl() { static_cast(layer_->layer())->ClearClient(); } blink::WebLayer* WebExternalTextureLayerImpl::layer() { return layer_.get(); } void WebExternalTextureLayerImpl::clearTexture() { TextureLayer* layer = static_cast(layer_->layer()); layer->ClearTexture(); } void WebExternalTextureLayerImpl::setOpaque(bool opaque) { static_cast(layer_->layer())->SetContentsOpaque(opaque); } void WebExternalTextureLayerImpl::setPremultipliedAlpha( bool premultiplied_alpha) { static_cast(layer_->layer()) ->SetPremultipliedAlpha(premultiplied_alpha); } void WebExternalTextureLayerImpl::setBlendBackgroundColor(bool blend) { static_cast(layer_->layer())->SetBlendBackgroundColor(blend); } void WebExternalTextureLayerImpl::setRateLimitContext(bool rate_limit) { static_cast(layer_->layer())->SetRateLimitContext(rate_limit); } void WebExternalTextureLayerImpl::setNearestNeighbor(bool nearest_neighbor) { static_cast(layer_->layer()) ->SetNearestNeighbor(nearest_neighbor); } bool WebExternalTextureLayerImpl::PrepareTextureMailbox( cc::TextureMailbox* mailbox, scoped_ptr* release_callback, bool use_shared_memory) { blink::WebExternalTextureMailbox client_mailbox; WebExternalBitmapImpl* bitmap = nullptr; if (use_shared_memory) bitmap = AllocateBitmap(); if (!client_->prepareMailbox(&client_mailbox, bitmap)) { if (bitmap) free_bitmaps_.push_back(bitmap); return false; } gpu::Mailbox name; name.SetName(client_mailbox.name); if (bitmap) { *mailbox = cc::TextureMailbox(bitmap->shared_bitmap(), bitmap->size()); } else { *mailbox = cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint); } mailbox->set_allow_overlay(client_mailbox.allowOverlay); mailbox->set_nearest_neighbor(client_mailbox.nearestNeighbor); if (mailbox->IsValid()) { *release_callback = cc::SingleReleaseCallback::Create( base::Bind(&WebExternalTextureLayerImpl::DidReleaseMailbox, this->AsWeakPtr(), client_mailbox, bitmap)); } return true; } WebExternalBitmapImpl* WebExternalTextureLayerImpl::AllocateBitmap() { if (!free_bitmaps_.empty()) { WebExternalBitmapImpl* result = free_bitmaps_.back(); free_bitmaps_.weak_erase(free_bitmaps_.end() - 1); return result; } return new WebExternalBitmapImpl; } // static void WebExternalTextureLayerImpl::DidReleaseMailbox( base::WeakPtr layer, const blink::WebExternalTextureMailbox& mailbox, WebExternalBitmapImpl* bitmap, unsigned sync_point, bool lost_resource) { DCHECK(layer); blink::WebExternalTextureMailbox available_mailbox; memcpy(available_mailbox.name, mailbox.name, sizeof(available_mailbox.name)); available_mailbox.syncPoint = sync_point; if (bitmap) layer->free_bitmaps_.push_back(bitmap); layer->client_->mailboxReleased(available_mailbox, lost_resource); } } // namespace cc_blink