Remove unused parameter.
[chromium-blink-merge.git] / ui / gl / gl_image_memory.cc
blob902291759eb066ca741833e50f304c435582e1ee
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/logging.h"
8 #include "base/trace_event/trace_event.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 ValidInternalFormat(unsigned internalformat) {
21 switch (internalformat) {
22 case GL_RGBA:
23 case GL_BGRA_EXT:
24 return true;
25 default:
26 return false;
30 bool ValidFormat(gfx::GpuMemoryBuffer::Format format) {
31 switch (format) {
32 case gfx::GpuMemoryBuffer::ATC:
33 case gfx::GpuMemoryBuffer::ATCIA:
34 case gfx::GpuMemoryBuffer::DXT1:
35 case gfx::GpuMemoryBuffer::DXT5:
36 case gfx::GpuMemoryBuffer::ETC1:
37 case gfx::GpuMemoryBuffer::RGBA_8888:
38 case gfx::GpuMemoryBuffer::BGRA_8888:
39 return true;
40 case gfx::GpuMemoryBuffer::RGBX_8888:
41 return false;
44 NOTREACHED();
45 return false;
48 bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) {
49 switch (format) {
50 case gfx::GpuMemoryBuffer::ATC:
51 case gfx::GpuMemoryBuffer::ATCIA:
52 case gfx::GpuMemoryBuffer::DXT1:
53 case gfx::GpuMemoryBuffer::DXT5:
54 case gfx::GpuMemoryBuffer::ETC1:
55 return true;
56 case gfx::GpuMemoryBuffer::RGBA_8888:
57 case gfx::GpuMemoryBuffer::BGRA_8888:
58 case gfx::GpuMemoryBuffer::RGBX_8888:
59 return false;
62 NOTREACHED();
63 return false;
66 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) {
67 switch (format) {
68 case gfx::GpuMemoryBuffer::ATC:
69 return GL_ATC_RGB_AMD;
70 case gfx::GpuMemoryBuffer::ATCIA:
71 return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
72 case gfx::GpuMemoryBuffer::DXT1:
73 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
74 case gfx::GpuMemoryBuffer::DXT5:
75 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
76 case gfx::GpuMemoryBuffer::ETC1:
77 return GL_ETC1_RGB8_OES;
78 case gfx::GpuMemoryBuffer::RGBA_8888:
79 return GL_RGBA;
80 case gfx::GpuMemoryBuffer::BGRA_8888:
81 return GL_BGRA_EXT;
82 case gfx::GpuMemoryBuffer::RGBX_8888:
83 NOTREACHED();
84 return 0;
87 NOTREACHED();
88 return 0;
91 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) {
92 return TextureFormat(format);
95 GLenum DataType(gfx::GpuMemoryBuffer::Format format) {
96 switch (format) {
97 case gfx::GpuMemoryBuffer::RGBA_8888:
98 case gfx::GpuMemoryBuffer::BGRA_8888:
99 return GL_UNSIGNED_BYTE;
100 case gfx::GpuMemoryBuffer::ATC:
101 case gfx::GpuMemoryBuffer::ATCIA:
102 case gfx::GpuMemoryBuffer::DXT1:
103 case gfx::GpuMemoryBuffer::DXT5:
104 case gfx::GpuMemoryBuffer::ETC1:
105 case gfx::GpuMemoryBuffer::RGBX_8888:
106 NOTREACHED();
107 return 0;
110 NOTREACHED();
111 return 0;
114 GLsizei SizeInBytes(const gfx::Size& size,
115 gfx::GpuMemoryBuffer::Format format) {
116 size_t stride_in_bytes = 0;
117 bool valid_stride = GLImageMemory::StrideInBytes(
118 size.width(), format, &stride_in_bytes);
119 DCHECK(valid_stride);
120 return static_cast<GLsizei>(stride_in_bytes * size.height());
123 } // namespace
125 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
126 : size_(size),
127 internalformat_(internalformat),
128 memory_(NULL),
129 format_(gfx::GpuMemoryBuffer::RGBA_8888),
130 in_use_(false),
131 target_(0),
132 need_do_bind_tex_image_(false)
133 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
134 defined(USE_OZONE)
136 egl_texture_id_(0u),
137 egl_image_(EGL_NO_IMAGE_KHR)
138 #endif
142 GLImageMemory::~GLImageMemory() {
143 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
144 defined(USE_OZONE)
145 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_);
146 DCHECK_EQ(0u, egl_texture_id_);
147 #endif
150 // static
151 bool GLImageMemory::StrideInBytes(size_t width,
152 gfx::GpuMemoryBuffer::Format format,
153 size_t* stride_in_bytes) {
154 base::CheckedNumeric<size_t> s = width;
155 switch (format) {
156 case gfx::GpuMemoryBuffer::ATCIA:
157 case gfx::GpuMemoryBuffer::DXT5:
158 *stride_in_bytes = width;
159 return true;
160 case gfx::GpuMemoryBuffer::ATC:
161 case gfx::GpuMemoryBuffer::DXT1:
162 case gfx::GpuMemoryBuffer::ETC1:
163 DCHECK_EQ(width % 2, 0U);
164 s /= 2;
165 if (!s.IsValid())
166 return false;
168 *stride_in_bytes = s.ValueOrDie();
169 return true;
170 case gfx::GpuMemoryBuffer::RGBA_8888:
171 case gfx::GpuMemoryBuffer::BGRA_8888:
172 s *= 4;
173 if (!s.IsValid())
174 return false;
176 *stride_in_bytes = s.ValueOrDie();
177 return true;
178 case gfx::GpuMemoryBuffer::RGBX_8888:
179 NOTREACHED();
180 return false;
183 NOTREACHED();
184 return false;
187 bool GLImageMemory::Initialize(const unsigned char* memory,
188 gfx::GpuMemoryBuffer::Format format) {
189 if (!ValidInternalFormat(internalformat_)) {
190 LOG(ERROR) << "Invalid internalformat: " << internalformat_;
191 return false;
194 if (!ValidFormat(format)) {
195 LOG(ERROR) << "Invalid format: " << format;
196 return false;
199 DCHECK(memory);
200 DCHECK(!memory_);
201 DCHECK_IMPLIES(IsCompressedFormat(format), size_.width() % 4 == 0);
202 DCHECK_IMPLIES(IsCompressedFormat(format), size_.height() % 4 == 0);
203 memory_ = memory;
204 format_ = format;
205 return true;
208 void GLImageMemory::Destroy(bool have_context) {
209 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
210 defined(USE_OZONE)
211 if (egl_image_ != EGL_NO_IMAGE_KHR) {
212 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_);
213 egl_image_ = EGL_NO_IMAGE_KHR;
216 if (egl_texture_id_) {
217 if (have_context)
218 glDeleteTextures(1, &egl_texture_id_);
219 egl_texture_id_ = 0u;
221 #endif
222 memory_ = NULL;
225 gfx::Size GLImageMemory::GetSize() {
226 return size_;
229 bool GLImageMemory::BindTexImage(unsigned target) {
230 if (target_ && target_ != target) {
231 LOG(ERROR) << "GLImage can only be bound to one target";
232 return false;
234 target_ = target;
236 // Defer DoBindTexImage if not currently in use.
237 if (!in_use_) {
238 need_do_bind_tex_image_ = true;
239 return true;
242 DoBindTexImage(target);
243 return true;
246 bool GLImageMemory::CopyTexImage(unsigned target) {
247 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage");
249 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target.
250 if (target == GL_TEXTURE_EXTERNAL_OES)
251 return false;
253 DCHECK(memory_);
254 if (IsCompressedFormat(format_)) {
255 glCompressedTexSubImage2D(target,
256 0, // level
257 0, // x-offset
258 0, // y-offset
259 size_.width(), size_.height(),
260 DataFormat(format_), SizeInBytes(size_, format_),
261 memory_);
262 } else {
263 glTexSubImage2D(target, 0, // level
264 0, // x
265 0, // y
266 size_.width(), size_.height(), DataFormat(format_),
267 DataType(format_), memory_);
270 return true;
273 void GLImageMemory::WillUseTexImage() {
274 DCHECK(!in_use_);
275 in_use_ = true;
277 if (!need_do_bind_tex_image_)
278 return;
280 DCHECK(target_);
281 DoBindTexImage(target_);
284 void GLImageMemory::DidUseTexImage() {
285 DCHECK(in_use_);
286 in_use_ = false;
289 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
290 int z_order,
291 OverlayTransform transform,
292 const Rect& bounds_rect,
293 const RectF& crop_rect) {
294 return false;
297 void GLImageMemory::DoBindTexImage(unsigned target) {
298 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage");
300 DCHECK(need_do_bind_tex_image_);
301 need_do_bind_tex_image_ = false;
303 DCHECK(memory_);
304 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
305 defined(USE_OZONE)
306 if (target == GL_TEXTURE_EXTERNAL_OES) {
307 if (egl_image_ == EGL_NO_IMAGE_KHR) {
308 DCHECK_EQ(0u, egl_texture_id_);
309 glGenTextures(1, &egl_texture_id_);
312 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
317 if (IsCompressedFormat(format_)) {
318 glCompressedTexImage2D(GL_TEXTURE_2D,
319 0, // mip level
320 TextureFormat(format_), size_.width(),
321 size_.height(),
322 0, // border
323 SizeInBytes(size_, format_), memory_);
324 } else {
325 glTexImage2D(GL_TEXTURE_2D,
326 0, // mip level
327 TextureFormat(format_),
328 size_.width(),
329 size_.height(),
330 0, // border
331 DataFormat(format_),
332 DataType(format_),
333 memory_);
337 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
338 // Need to pass current EGL rendering context to eglCreateImageKHR for
339 // target type EGL_GL_TEXTURE_2D_KHR.
340 egl_image_ =
341 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
342 eglGetCurrentContext(),
343 EGL_GL_TEXTURE_2D_KHR,
344 reinterpret_cast<EGLClientBuffer>(egl_texture_id_),
345 attrs);
346 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_)
347 << "Error creating EGLImage: " << eglGetError();
348 } else {
349 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_);
351 if (IsCompressedFormat(format_)) {
352 glCompressedTexSubImage2D(GL_TEXTURE_2D,
353 0, // mip level
354 0, // x-offset
355 0, // y-offset
356 size_.width(), size_.height(),
357 DataFormat(format_),
358 SizeInBytes(size_, format_),
359 memory_);
360 } else {
361 glTexSubImage2D(GL_TEXTURE_2D,
362 0, // mip level
363 0, // x-offset
364 0, // y-offset
365 size_.width(),
366 size_.height(),
367 DataFormat(format_),
368 DataType(format_),
369 memory_);
373 glEGLImageTargetTexture2DOES(target, egl_image_);
374 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
375 return;
377 #endif
379 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target);
380 if (IsCompressedFormat(format_)) {
381 glCompressedTexImage2D(target,
382 0, // mip level
383 TextureFormat(format_), size_.width(),
384 size_.height(),
385 0, // border
386 SizeInBytes(size_, format_), memory_);
387 } else {
388 glTexImage2D(target,
389 0, // mip level
390 TextureFormat(format_),
391 size_.width(),
392 size_.height(),
393 0, // border
394 DataFormat(format_),
395 DataType(format_),
396 memory_);
400 } // namespace gfx