1 // Copyright (c) 2012 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.
5 #include "content/browser/renderer_host/surface_texture_transport_client_android.h"
7 #include <android/native_window_jni.h>
10 #include "cc/layers/video_layer.h"
11 #include "content/browser/gpu/gpu_surface_tracker.h"
12 #include "content/browser/renderer_host/compositor_impl_android.h"
13 #include "content/browser/renderer_host/image_transport_factory_android.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
16 #include "third_party/khronos/GLES2/gl2.h"
17 #include "third_party/khronos/GLES2/gl2ext.h"
18 #include "ui/gl/android/surface_texture_bridge.h"
24 static const uint32 kGLTextureExternalOES
= 0x8D65;
26 class SurfaceRefAndroid
: public GpuSurfaceTracker::SurfaceRef
{
29 const scoped_refptr
<gfx::SurfaceTextureBridge
>& surface
,
30 ANativeWindow
* window
)
33 ANativeWindow_acquire(window_
);
37 virtual ~SurfaceRefAndroid() {
39 ANativeWindow_release(window_
);
42 scoped_refptr
<gfx::SurfaceTextureBridge
> surface_
;
43 ANativeWindow
* window_
;
46 } // anonymous namespace
48 SurfaceTextureTransportClient::SurfaceTextureTransportClient()
51 texture_mailbox_sync_point_(0),
56 SurfaceTextureTransportClient::~SurfaceTextureTransportClient() {
59 scoped_refptr
<cc::Layer
> SurfaceTextureTransportClient::Initialize() {
60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
61 // Use a SurfaceTexture to stream frames to the UI thread.
62 video_layer_
= cc::VideoLayer::Create(this);
64 surface_texture_
= new gfx::SurfaceTextureBridge(0);
65 surface_texture_
->SetFrameAvailableCallback(
67 &SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable
,
68 weak_factory_
.GetWeakPtr()));
69 surface_texture_
->DetachFromGLContext();
70 return video_layer_
.get();
74 SurfaceTextureTransportClient::GetCompositingSurface(int surface_id
) {
76 surface_id_
= surface_id
;
79 window_
= surface_texture_
->CreateSurface();
81 GpuSurfaceTracker::Get()->SetNativeWidget(
82 surface_id
, window_
, new SurfaceRefAndroid(surface_texture_
, window_
));
83 // SurfaceRefAndroid took ownership (and an extra ref to) window_.
84 ANativeWindow_release(window_
);
87 return gfx::GLSurfaceHandle(gfx::kNullPluginWindow
, gfx::NATIVE_DIRECT
);
90 void SurfaceTextureTransportClient::SetSize(const gfx::Size
& size
) {
91 if (size
.width() > 0 && size
.height() > 0) {
92 surface_texture_
->SetDefaultBufferSize(size
.width(), size
.height());
94 video_layer_
->SetBounds(size
);
98 scoped_refptr
<media::VideoFrame
> SurfaceTextureTransportClient::
101 WebKit::WebGraphicsContext3D
* context
=
102 ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
103 context
->makeContextCurrent();
104 texture_id_
= context
->createTexture();
105 context
->bindTexture(GL_TEXTURE_EXTERNAL_OES
, texture_id_
);
107 surface_texture_
->AttachToGLContext();
109 context
->genMailboxCHROMIUM(texture_mailbox_
.name
);
110 context
->produceTextureCHROMIUM(kGLTextureExternalOES
,
111 texture_mailbox_
.name
);
112 texture_mailbox_sync_point_
= context
->insertSyncPoint();
114 if (!video_frame_
.get()) {
115 const gfx::Size size
= video_layer_
->bounds();
116 video_frame_
= media::VideoFrame::WrapNativeTexture(
117 new media::VideoFrame::MailboxHolder(
119 texture_mailbox_sync_point_
,
120 media::VideoFrame::MailboxHolder::TextureNoLongerNeededCallback()),
121 kGLTextureExternalOES
,
123 gfx::Rect(gfx::Point(), size
),
126 media::VideoFrame::ReadPixelsCB(),
129 surface_texture_
->UpdateTexImage();
134 void SurfaceTextureTransportClient::PutCurrentFrame(
135 const scoped_refptr
<media::VideoFrame
>& frame
) {
138 void SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable() {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
140 video_layer_
->SetNeedsDisplay();
143 } // namespace content