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) || \
14 #include "ui/gl/gl_surface_egl.h"
20 bool ValidFormat(unsigned internalformat
) {
21 switch (internalformat
) {
30 GLenum
TextureFormat(unsigned internalformat
) {
31 switch (internalformat
) {
42 GLenum
DataFormat(unsigned internalformat
) {
43 return TextureFormat(internalformat
);
46 GLenum
DataType(unsigned internalformat
) {
47 switch (internalformat
) {
50 return GL_UNSIGNED_BYTE
;
57 int BytesPerPixel(unsigned internalformat
) {
58 switch (internalformat
) {
70 GLImageMemory::GLImageMemory(const gfx::Size
& size
, unsigned internalformat
)
73 internalformat_(internalformat
)
74 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
78 egl_image_(EGL_NO_IMAGE_KHR
)
83 GLImageMemory::~GLImageMemory() {
84 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
86 DCHECK_EQ(EGL_NO_IMAGE_KHR
, egl_image_
);
87 DCHECK_EQ(0u, egl_texture_id_
);
91 bool GLImageMemory::Initialize(const unsigned char* memory
) {
92 if (!ValidFormat(internalformat_
)) {
93 DVLOG(0) << "Invalid format: " << internalformat_
;
103 void GLImageMemory::Destroy(bool have_context
) {
104 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
106 if (egl_image_
!= EGL_NO_IMAGE_KHR
) {
107 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_
);
108 egl_image_
= EGL_NO_IMAGE_KHR
;
111 if (egl_texture_id_
) {
113 glDeleteTextures(1, &egl_texture_id_
);
114 egl_texture_id_
= 0u;
120 gfx::Size
GLImageMemory::GetSize() {
124 bool GLImageMemory::BindTexImage(unsigned target
) {
125 TRACE_EVENT0("gpu", "GLImageMemory::BindTexImage");
128 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
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_
);
136 ScopedTextureBinder
texture_binder(GL_TEXTURE_2D
, egl_texture_id_
);
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
,
143 TextureFormat(internalformat_
),
147 DataFormat(internalformat_
),
148 DataType(internalformat_
),
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.
156 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
157 eglGetCurrentContext(),
158 EGL_GL_TEXTURE_2D_KHR
,
159 reinterpret_cast<EGLClientBuffer
>(egl_texture_id_
),
161 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_
)
162 << "Error creating EGLImage: " << eglGetError();
164 ScopedTextureBinder
texture_binder(GL_TEXTURE_2D
, egl_texture_id_
);
166 glTexSubImage2D(GL_TEXTURE_2D
,
172 DataFormat(internalformat_
),
173 DataType(internalformat_
),
177 glEGLImageTargetTexture2DOES(target
, egl_image_
);
178 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
184 DCHECK_NE(static_cast<GLenum
>(GL_TEXTURE_EXTERNAL_OES
), target
);
187 TextureFormat(internalformat_
),
191 DataFormat(internalformat_
),
192 DataType(internalformat_
),
198 bool GLImageMemory::HasValidFormat() const {
199 return ValidFormat(internalformat_
);
202 size_t GLImageMemory::Bytes() const {
203 return size_
.GetArea() * BytesPerPixel(internalformat_
);
206 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
208 OverlayTransform transform
,
209 const Rect
& bounds_rect
,
210 const RectF
& crop_rect
) {