cc: Add more eviction categories to picture layer impl.
[chromium-blink-merge.git] / ui / gl / gl_image_memory.cc
blobdfd3d2cb95c3b55df7c515411551d08f3fb4c72f
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 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \
75 defined(USE_OZONE)
77 egl_texture_id_(0u),
78 egl_image_(EGL_NO_IMAGE_KHR)
79 #endif
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
91 bool GLImageMemory::Initialize(const unsigned char* memory) {
92 if (!ValidFormat(internalformat_)) {
93 DVLOG(0) << "Invalid format: " << internalformat_;
94 return false;
97 DCHECK(memory);
98 DCHECK(!memory_);
99 memory_ = memory;
100 return true;
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;
111 if (egl_texture_id_) {
112 if (have_context)
113 glDeleteTextures(1, &egl_texture_id_);
114 egl_texture_id_ = 0u;
116 #endif
117 memory_ = NULL;
120 gfx::Size GLImageMemory::GetSize() {
121 return size_;
124 bool GLImageMemory::BindTexImage(unsigned target) {
125 TRACE_EVENT0("gpu", "GLImageMemory::BindTexImage");
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_);
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,
142 0, // mip level
143 TextureFormat(internalformat_),
144 size_.width(),
145 size_.height(),
146 0, // border
147 DataFormat(internalformat_),
148 DataType(internalformat_),
149 memory_);
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_);
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_);
177 glEGLImageTargetTexture2DOES(target, egl_image_);
178 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
180 return true;
182 #endif
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_);
195 return true;
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,
207 int z_order,
208 OverlayTransform transform,
209 const Rect& bounds_rect,
210 const RectF& crop_rect) {
211 return false;
214 } // namespace gfx