Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / surface_texture_transport_client_android.cc
blobb563480efd94c65fc168c68116c0f3849ed87c61
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>
9 #include "base/bind.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"
20 namespace content {
22 namespace {
24 static const uint32 kGLTextureExternalOES = 0x8D65;
26 class SurfaceRefAndroid : public GpuSurfaceTracker::SurfaceRef {
27 public:
28 SurfaceRefAndroid(
29 const scoped_refptr<gfx::SurfaceTextureBridge>& surface,
30 ANativeWindow* window)
31 : surface_(surface),
32 window_(window) {
33 ANativeWindow_acquire(window_);
36 private:
37 virtual ~SurfaceRefAndroid() {
38 DCHECK(window_);
39 ANativeWindow_release(window_);
42 scoped_refptr<gfx::SurfaceTextureBridge> surface_;
43 ANativeWindow* window_;
46 } // anonymous namespace
48 SurfaceTextureTransportClient::SurfaceTextureTransportClient()
49 : window_(NULL),
50 texture_id_(0),
51 texture_mailbox_sync_point_(0),
52 surface_id_(0),
53 weak_factory_(this) {
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(
66 base::Bind(
67 &SurfaceTextureTransportClient::OnSurfaceTextureFrameAvailable,
68 weak_factory_.GetWeakPtr()));
69 surface_texture_->DetachFromGLContext();
70 return video_layer_.get();
73 gfx::GLSurfaceHandle
74 SurfaceTextureTransportClient::GetCompositingSurface(int surface_id) {
75 DCHECK(surface_id);
76 surface_id_ = surface_id;
78 if (!window_) {
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);
95 video_frame_ = NULL;
98 scoped_refptr<media::VideoFrame> SurfaceTextureTransportClient::
99 GetCurrentFrame() {
100 if (!texture_id_) {
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_);
106 context->flush();
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(
118 texture_mailbox_,
119 texture_mailbox_sync_point_,
120 media::VideoFrame::MailboxHolder::TextureNoLongerNeededCallback()),
121 kGLTextureExternalOES,
122 size,
123 gfx::Rect(gfx::Point(), size),
124 size,
125 base::TimeDelta(),
126 media::VideoFrame::ReadPixelsCB(),
127 base::Closure());
129 surface_texture_->UpdateTexImage();
131 return video_frame_;
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