Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / gl / gl_image_android_native_buffer.cc
1 // Copyright 2014 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.
4
5 #include "ui/gl/gl_image_android_native_buffer.h"
6
7 #include "ui/gl/gl_surface_egl.h"
8 #include "ui/gl/scoped_binders.h"
9
10 namespace gfx {
11
12 GLImageAndroidNativeBuffer::GLImageAndroidNativeBuffer(const gfx::Size& size)
13     : GLImageEGL(size),
14       release_after_use_(false),
15       in_use_(false),
16       target_(0),
17       egl_image_for_unbind_(EGL_NO_IMAGE_KHR),
18       texture_id_for_unbind_(0) {
19 }
20
21 GLImageAndroidNativeBuffer::~GLImageAndroidNativeBuffer() {
22   DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
23   DCHECK_EQ(0u, texture_id_for_unbind_);
24 }
25
26 bool GLImageAndroidNativeBuffer::Initialize(EGLClientBuffer native_buffer) {
27   EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
28   return GLImageEGL::Initialize(
29       EGL_NATIVE_BUFFER_ANDROID, native_buffer, attrs);
30 }
31
32 void GLImageAndroidNativeBuffer::Destroy(bool have_context) {
33   if (egl_image_for_unbind_ != EGL_NO_IMAGE_KHR) {
34     eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
35                        egl_image_for_unbind_);
36     egl_image_for_unbind_ = EGL_NO_IMAGE_KHR;
37   }
38
39   if (texture_id_for_unbind_) {
40     if (have_context)
41       glDeleteTextures(1, &texture_id_for_unbind_);
42     texture_id_for_unbind_ = 0u;
43   }
44
45   GLImageEGL::Destroy(have_context);
46 }
47
48 bool GLImageAndroidNativeBuffer::BindTexImage(unsigned target) {
49   DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
50
51   if (target == GL_TEXTURE_RECTANGLE_ARB) {
52     LOG(ERROR) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target";
53     return false;
54   }
55
56   if (target_ && target_ != target) {
57     LOG(ERROR) << "EGLImage can only be bound to one target";
58     return false;
59   }
60   target_ = target;
61
62   // Defer ImageTargetTexture2D if not currently in use.
63   if (!in_use_)
64     return true;
65
66   glEGLImageTargetTexture2DOES(target_, egl_image_);
67   DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
68   return true;
69 }
70
71 void GLImageAndroidNativeBuffer::WillUseTexImage() {
72   DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
73   DCHECK(!in_use_);
74   in_use_ = true;
75   glEGLImageTargetTexture2DOES(target_, egl_image_);
76   DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
77 }
78
79 void GLImageAndroidNativeBuffer::DidUseTexImage() {
80   DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
81   DCHECK(in_use_);
82   in_use_ = false;
83
84   if (!release_after_use_)
85     return;
86
87   if (egl_image_for_unbind_ == EGL_NO_IMAGE_KHR) {
88     DCHECK_EQ(0u, texture_id_for_unbind_);
89     glGenTextures(1, &texture_id_for_unbind_);
90
91     {
92       ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_for_unbind_);
93       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
94       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
95       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
96
97       char zero[4] = {0, };
98       glTexImage2D(
99           GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero);
100     }
101
102     EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
103     // Need to pass current EGL rendering context to eglCreateImageKHR for
104     // target type EGL_GL_TEXTURE_2D_KHR.
105     egl_image_for_unbind_ = eglCreateImageKHR(
106         GLSurfaceEGL::GetHardwareDisplay(),
107         eglGetCurrentContext(),
108         EGL_GL_TEXTURE_2D_KHR,
109         reinterpret_cast<EGLClientBuffer>(texture_id_for_unbind_),
110         attrs);
111     DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_for_unbind_)
112         << "Error creating EGLImage: " << eglGetError();
113   }
114
115   glEGLImageTargetTexture2DOES(target_, egl_image_for_unbind_);
116   DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
117 }
118
119 bool GLImageAndroidNativeBuffer::ScheduleOverlayPlane(
120     gfx::AcceleratedWidget widget,
121     int z_order,
122     OverlayTransform transform,
123     const Rect& bounds_rect,
124     const RectF& crop_rect) {
125   return false;
126 }
127
128 void GLImageAndroidNativeBuffer::SetReleaseAfterUse() {
129   release_after_use_ = true;
130 }
131
132 }  // namespace gfx