1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/compositor_bindings/web_external_texture_layer_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/texture_layer.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/resource_update_queue.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "cc/resources/single_release_callback.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "cc/resources/texture_mailbox.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/compositor_bindings/web_external_bitmap_impl.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/compositor_bindings/web_layer_impl.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebExternalTextureMailbox.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebFloatRect.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebSize.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using cc::TextureLayer;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using cc::ResourceUpdateQueue;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace content {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebExternalTextureLayerImpl::WebExternalTextureLayerImpl(
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebExternalTextureLayerClient* client)
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : client_(client) {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  cc::TextureLayerClient* cc_client = client_ ? this : NULL;
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(cc_client);
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetIsDrawable(true);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_.reset(new WebLayerImpl(layer));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebExternalTextureLayerImpl::~WebExternalTextureLayerImpl() {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static_cast<TextureLayer*>(layer_->layer())->ClearClient();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)blink::WebLayer* WebExternalTextureLayerImpl::layer() {
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return layer_.get();
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebExternalTextureLayerImpl::clearTexture() {
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TextureLayer* layer = static_cast<TextureLayer*>(layer_->layer());
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  layer->ClearTexture();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebExternalTextureLayerImpl::setOpaque(bool opaque) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static_cast<TextureLayer*>(layer_->layer())->SetContentsOpaque(opaque);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebExternalTextureLayerImpl::setPremultipliedAlpha(
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool premultiplied_alpha) {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static_cast<TextureLayer*>(layer_->layer())->SetPremultipliedAlpha(
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      premultiplied_alpha);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid WebExternalTextureLayerImpl::setBlendBackgroundColor(bool blend) {
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<TextureLayer*>(layer_->layer())->SetBlendBackgroundColor(blend);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebExternalTextureLayerImpl::setRateLimitContext(bool rate_limit) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static_cast<TextureLayer*>(layer_->layer())->SetRateLimitContext(rate_limit);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool WebExternalTextureLayerImpl::PrepareTextureMailbox(
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    cc::TextureMailbox* mailbox,
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<cc::SingleReleaseCallback>* release_callback,
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool use_shared_memory) {
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebExternalTextureMailbox client_mailbox;
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebExternalBitmapImpl* bitmap = NULL;
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (use_shared_memory)
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bitmap = AllocateBitmap();
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!client_->prepareMailbox(&client_mailbox, bitmap)) {
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (bitmap)
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      free_bitmaps_.push_back(bitmap);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gpu::Mailbox name;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  name.SetName(client_mailbox.name);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bitmap) {
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    *mailbox = cc::TextureMailbox(bitmap->shared_memory(), bitmap->size());
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *mailbox =
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint);
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  mailbox->set_allow_overlay(client_mailbox.allowOverlay);
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (mailbox->IsValid()) {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    *release_callback = cc::SingleReleaseCallback::Create(
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&WebExternalTextureLayerImpl::DidReleaseMailbox,
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   this->AsWeakPtr(),
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   client_mailbox,
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   bitmap));
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochWebExternalBitmapImpl* WebExternalTextureLayerImpl::AllocateBitmap() {
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!free_bitmaps_.empty()) {
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    WebExternalBitmapImpl* result = free_bitmaps_.back();
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    free_bitmaps_.weak_erase(free_bitmaps_.end() - 1);
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return result;
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return new WebExternalBitmapImpl;
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebExternalTextureLayerImpl::DidReleaseMailbox(
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::WeakPtr<WebExternalTextureLayerImpl> layer,
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebExternalTextureMailbox& mailbox,
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    WebExternalBitmapImpl* bitmap,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned sync_point,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool lost_resource) {
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (lost_resource || !layer) {
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    delete bitmap;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebExternalTextureMailbox available_mailbox;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  memcpy(available_mailbox.name, mailbox.name, sizeof(available_mailbox.name));
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  available_mailbox.syncPoint = sync_point;
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (bitmap)
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    layer->free_bitmaps_.push_back(bitmap);
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  layer->client_->mailboxReleased(available_mailbox);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace content
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
131