Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / gl / gl_image_memory.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_memory.h"
6
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9 #include "ui/gl/gl_bindings.h"
10 #include "ui/gl/scoped_binders.h"
11
12 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
13     defined(USE_OZONE)
14 #include "ui/gl/gl_surface_egl.h"
15 #endif
16
17 namespace gfx {
18 namespace {
19
20 bool ValidFormat(unsigned internalformat) {
21   switch (internalformat) {
22     case GL_BGRA8_EXT:
23     case GL_RGBA8_OES:
24       return true;
25     default:
26       return false;
27   }
28 }
29
30 GLenum TextureFormat(unsigned internalformat) {
31   switch (internalformat) {
32     case GL_BGRA8_EXT:
33       return GL_BGRA_EXT;
34     case GL_RGBA8_OES:
35       return GL_RGBA;
36     default:
37       NOTREACHED();
38       return 0;
39   }
40 }
41
42 GLenum DataFormat(unsigned internalformat) {
43   return TextureFormat(internalformat);
44 }
45
46 GLenum DataType(unsigned internalformat) {
47   switch (internalformat) {
48     case GL_BGRA8_EXT:
49     case GL_RGBA8_OES:
50       return GL_UNSIGNED_BYTE;
51     default:
52       NOTREACHED();
53       return 0;
54   }
55 }
56
57 int BytesPerPixel(unsigned internalformat) {
58   switch (internalformat) {
59     case GL_BGRA8_EXT:
60     case GL_RGBA8_OES:
61       return 4;
62     default:
63       NOTREACHED();
64       return 0;
65   }
66 }
67
68 }  // namespace
69
70 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
71     : memory_(NULL),
72       size_(size),
73       internalformat_(internalformat)
74 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
75     defined(USE_OZONE)
76       ,
77       egl_texture_id_(0u),
78       egl_image_(EGL_NO_IMAGE_KHR)
79 #endif
80 {
81 }
82
83 GLImageMemory::~GLImageMemory() {
84 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
85     defined(USE_OZONE)
86   DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
87   DCHECK_EQ(0u, egl_texture_id_);
88 #endif
89 }
90
91 bool GLImageMemory::Initialize(const unsigned char* memory) {
92   if (!ValidFormat(internalformat_)) {
93     DVLOG(0) << "Invalid format: " << internalformat_;
94     return false;
95   }
96
97   DCHECK(memory);
98   DCHECK(!memory_);
99   memory_ = memory;
100   return true;
101 }
102
103 void GLImageMemory::Destroy(bool have_context) {
104 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
105     defined(USE_OZONE)
106   if (egl_image_ != EGL_NO_IMAGE_KHR) {
107     eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_);
108     egl_image_ = EGL_NO_IMAGE_KHR;
109   }
110
111   if (egl_texture_id_) {
112     if (have_context)
113       glDeleteTextures(1, &egl_texture_id_);
114     egl_texture_id_ = 0u;
115   }
116 #endif
117   memory_ = NULL;
118 }
119
120 gfx::Size GLImageMemory::GetSize() {
121   return size_;
122 }
123
124 bool GLImageMemory::BindTexImage(unsigned target) {
125   TRACE_EVENT0("gpu", "GLImageMemory::BindTexImage");
126
127   DCHECK(memory_);
128 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
129     defined(USE_OZONE)
130   if (target == GL_TEXTURE_EXTERNAL_OES) {
131     if (egl_image_ == EGL_NO_IMAGE_KHR) {
132       DCHECK_EQ(0u, egl_texture_id_);
133       glGenTextures(1, &egl_texture_id_);
134
135       {
136         ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
137
138         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
139         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
140         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
141         glTexImage2D(GL_TEXTURE_2D,
142                      0,  // mip level
143                      TextureFormat(internalformat_),
144                      size_.width(),
145                      size_.height(),
146                      0,  // border
147                      DataFormat(internalformat_),
148                      DataType(internalformat_),
149                      memory_);
150       }
151
152       EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
153       // Need to pass current EGL rendering context to eglCreateImageKHR for
154       // target type EGL_GL_TEXTURE_2D_KHR.
155       egl_image_ =
156           eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
157                             eglGetCurrentContext(),
158                             EGL_GL_TEXTURE_2D_KHR,
159                             reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
160                             attrs);
161       DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
162           << "Error creating EGLImage: " << eglGetError();
163     } else {
164       ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
165
166       glTexSubImage2D(GL_TEXTURE_2D,
167                       0,  // mip level
168                       0,  // x-offset
169                       0,  // y-offset
170                       size_.width(),
171                       size_.height(),
172                       DataFormat(internalformat_),
173                       DataType(internalformat_),
174                       memory_);
175     }
176
177     glEGLImageTargetTexture2DOES(target, egl_image_);
178     DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
179
180     return true;
181   }
182 #endif
183
184   DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
185   glTexImage2D(target,
186                0,  // mip level
187                TextureFormat(internalformat_),
188                size_.width(),
189                size_.height(),
190                0,  // border
191                DataFormat(internalformat_),
192                DataType(internalformat_),
193                memory_);
194
195   return true;
196 }
197
198 bool GLImageMemory::HasValidFormat() const {
199   return ValidFormat(internalformat_);
200 }
201
202 size_t GLImageMemory::Bytes() const {
203   return size_.GetArea() * BytesPerPixel(internalformat_);
204 }
205
206 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
207                                          int z_order,
208                                          OverlayTransform transform,
209                                          const Rect& bounds_rect,
210                                          const RectF& crop_rect) {
211   return false;
212 }
213
214 }  // namespace gfx