Fix android webview test shell command line file path for Telemetry
[chromium-blink-merge.git] / ui / gl / gl_image_memory.cc
blobd79a753fb846dc1eac767ab691bc7b3009a55c50
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.
5 #include "ui/gl/gl_image_memory.h"
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"
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
17 namespace gfx {
18 namespace {
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;
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;
42 GLenum DataFormat(unsigned internalformat) {
43 return TextureFormat(internalformat);
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;
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;
68 } // namespace
70 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
71 : memory_(NULL),
72 size_(size),
73 internalformat_(internalformat),
74 in_use_(false),
75 target_(0),
76 need_do_bind_tex_image_(false)
77 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
78 defined(USE_OZONE)
80 egl_texture_id_(0u),
81 egl_image_(EGL_NO_IMAGE_KHR)
82 #endif
86 GLImageMemory::~GLImageMemory() {
87 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
88 defined(USE_OZONE)
89 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
90 DCHECK_EQ(0u, egl_texture_id_);
91 #endif
94 bool GLImageMemory::Initialize(const unsigned char* memory) {
95 if (!ValidFormat(internalformat_)) {
96 DVLOG(0) << "Invalid format: " << internalformat_;
97 return false;
100 DCHECK(memory);
101 DCHECK(!memory_);
102 memory_ = memory;
103 return true;
106 void GLImageMemory::Destroy(bool have_context) {
107 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
108 defined(USE_OZONE)
109 if (egl_image_ != EGL_NO_IMAGE_KHR) {
110 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_);
111 egl_image_ = EGL_NO_IMAGE_KHR;
114 if (egl_texture_id_) {
115 if (have_context)
116 glDeleteTextures(1, &egl_texture_id_);
117 egl_texture_id_ = 0u;
119 #endif
120 memory_ = NULL;
123 gfx::Size GLImageMemory::GetSize() {
124 return size_;
127 bool GLImageMemory::BindTexImage(unsigned target) {
128 if (target_ && target_ != target) {
129 LOG(ERROR) << "GLImage can only be bound to one target";
130 return false;
132 target_ = target;
134 // Defer DoBindTexImage if not currently in use.
135 if (!in_use_) {
136 need_do_bind_tex_image_ = true;
137 return true;
140 DoBindTexImage(target);
141 return true;
144 bool GLImageMemory::CopyTexImage(unsigned target) {
145 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage");
147 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target.
148 if (target == GL_TEXTURE_EXTERNAL_OES)
149 return false;
151 DCHECK(memory_);
152 glTexImage2D(target,
153 0, // mip level
154 TextureFormat(internalformat_),
155 size_.width(),
156 size_.height(),
157 0, // border
158 DataFormat(internalformat_),
159 DataType(internalformat_),
160 memory_);
162 return true;
165 void GLImageMemory::WillUseTexImage() {
166 DCHECK(!in_use_);
167 in_use_ = true;
169 if (!need_do_bind_tex_image_)
170 return;
172 DCHECK(target_);
173 DoBindTexImage(target_);
176 void GLImageMemory::DidUseTexImage() {
177 DCHECK(in_use_);
178 in_use_ = false;
181 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
182 int z_order,
183 OverlayTransform transform,
184 const Rect& bounds_rect,
185 const RectF& crop_rect) {
186 return false;
189 bool GLImageMemory::HasValidFormat() const {
190 return ValidFormat(internalformat_);
193 size_t GLImageMemory::Bytes() const {
194 return size_.GetArea() * BytesPerPixel(internalformat_);
197 void GLImageMemory::DoBindTexImage(unsigned target) {
198 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage");
200 DCHECK(need_do_bind_tex_image_);
201 need_do_bind_tex_image_ = false;
203 DCHECK(memory_);
204 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
205 defined(USE_OZONE)
206 if (target == GL_TEXTURE_EXTERNAL_OES) {
207 if (egl_image_ == EGL_NO_IMAGE_KHR) {
208 DCHECK_EQ(0u, egl_texture_id_);
209 glGenTextures(1, &egl_texture_id_);
212 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
217 glTexImage2D(GL_TEXTURE_2D,
218 0, // mip level
219 TextureFormat(internalformat_),
220 size_.width(),
221 size_.height(),
222 0, // border
223 DataFormat(internalformat_),
224 DataType(internalformat_),
225 memory_);
228 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
229 // Need to pass current EGL rendering context to eglCreateImageKHR for
230 // target type EGL_GL_TEXTURE_2D_KHR.
231 egl_image_ =
232 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
233 eglGetCurrentContext(),
234 EGL_GL_TEXTURE_2D_KHR,
235 reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
236 attrs);
237 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
238 << "Error creating EGLImage: " << eglGetError();
239 } else {
240 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
242 glTexSubImage2D(GL_TEXTURE_2D,
243 0, // mip level
244 0, // x-offset
245 0, // y-offset
246 size_.width(),
247 size_.height(),
248 DataFormat(internalformat_),
249 DataType(internalformat_),
250 memory_);
253 glEGLImageTargetTexture2DOES(target, egl_image_);
254 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
255 return;
257 #endif
259 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
260 glTexImage2D(target,
261 0, // mip level
262 TextureFormat(internalformat_),
263 size_.width(),
264 size_.height(),
265 0, // border
266 DataFormat(internalformat_),
267 DataType(internalformat_),
268 memory_);
271 } // namespace gfx