| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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_shm.h" | |
| 6 | |
| 7 #include "base/debug/trace_event.h" | |
| 8 #include "base/process/process_handle.h" | |
| 9 #include "ui/gl/scoped_binders.h" | |
| 10 | |
| 11 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | |
| 12 defined(USE_OZONE) | |
| 13 #include "ui/gl/gl_surface_egl.h" | |
| 14 #endif | |
| 15 | |
| 16 namespace gfx { | |
| 17 | |
| 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 GLenum 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 GLImageShm::GLImageShm(gfx::Size size, unsigned internalformat) | |
| 71 : size_(size), | |
| 72 internalformat_(internalformat) | |
| 73 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | |
| 74 defined(USE_OZONE) | |
| 75 , | |
| 76 egl_texture_id_(0u), | |
| 77 egl_image_(EGL_NO_IMAGE_KHR) | |
| 78 #endif | |
| 79 { | |
| 80 } | |
| 81 | |
| 82 GLImageShm::~GLImageShm() { Destroy(); } | |
| 83 | |
| 84 bool GLImageShm::Initialize(gfx::GpuMemoryBufferHandle buffer) { | |
| 85 if (!ValidFormat(internalformat_)) { | |
| 86 DVLOG(0) << "Invalid format: " << internalformat_; | |
| 87 return false; | |
| 88 } | |
| 89 | |
| 90 if (!base::SharedMemory::IsHandleValid(buffer.handle)) | |
| 91 return false; | |
| 92 | |
| 93 base::SharedMemory shared_memory(buffer.handle, true); | |
| 94 | |
| 95 // Duplicate the handle. | |
| 96 base::SharedMemoryHandle duped_shared_memory_handle; | |
| 97 if (!shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), | |
| 98 &duped_shared_memory_handle)) { | |
| 99 DVLOG(0) << "Failed to duplicate shared memory handle."; | |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 shared_memory_.reset( | |
| 104 new base::SharedMemory(duped_shared_memory_handle, true)); | |
| 105 return true; | |
| 106 } | |
| 107 | |
| 108 void GLImageShm::Destroy() { | |
| 109 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | |
| 110 defined(USE_OZONE) | |
| 111 if (egl_image_ != EGL_NO_IMAGE_KHR) { | |
| 112 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); | |
| 113 egl_image_ = EGL_NO_IMAGE_KHR; | |
| 114 } | |
| 115 | |
| 116 if (egl_texture_id_) { | |
| 117 glDeleteTextures(1, &egl_texture_id_); | |
| 118 egl_texture_id_ = 0u; | |
| 119 } | |
| 120 #endif | |
| 121 } | |
| 122 | |
| 123 gfx::Size GLImageShm::GetSize() { return size_; } | |
| 124 | |
| 125 bool GLImageShm::BindTexImage(unsigned target) { | |
| 126 TRACE_EVENT0("gpu", "GLImageShm::BindTexImage"); | |
| 127 DCHECK(shared_memory_); | |
| 128 DCHECK(ValidFormat(internalformat_)); | |
| 129 | |
| 130 size_t size = size_.GetArea() * BytesPerPixel(internalformat_); | |
| 131 DCHECK(!shared_memory_->memory()); | |
| 132 if (!shared_memory_->Map(size)) { | |
| 133 DVLOG(0) << "Failed to map shared memory."; | |
| 134 return false; | |
| 135 } | |
| 136 | |
| 137 DCHECK(shared_memory_->memory()); | |
| 138 | |
| 139 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | |
| 140 defined(USE_OZONE) | |
| 141 if (target == GL_TEXTURE_EXTERNAL_OES) { | |
| 142 if (egl_image_ == EGL_NO_IMAGE_KHR) { | |
| 143 DCHECK_EQ(0u, egl_texture_id_); | |
| 144 glGenTextures(1, &egl_texture_id_); | |
| 145 | |
| 146 { | |
| 147 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | |
| 148 | |
| 149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 152 glTexImage2D(GL_TEXTURE_2D, | |
| 153 0, // mip level | |
| 154 TextureFormat(internalformat_), | |
| 155 size_.width(), | |
| 156 size_.height(), | |
| 157 0, // border | |
| 158 DataFormat(internalformat_), | |
| 159 DataType(internalformat_), | |
| 160 shared_memory_->memory()); | |
| 161 } | |
| 162 | |
| 163 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | |
| 164 // Need to pass current EGL rendering context to eglCreateImageKHR for | |
| 165 // target type EGL_GL_TEXTURE_2D_KHR. | |
| 166 egl_image_ = | |
| 167 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | |
| 168 eglGetCurrentContext(), | |
| 169 EGL_GL_TEXTURE_2D_KHR, | |
| 170 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), | |
| 171 attrs); | |
| 172 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) | |
| 173 << "Error creating EGLImage: " << eglGetError(); | |
| 174 } else { | |
| 175 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | |
| 176 | |
| 177 glTexSubImage2D(GL_TEXTURE_2D, | |
| 178 0, // mip level | |
| 179 0, // x-offset | |
| 180 0, // y-offset | |
| 181 size_.width(), | |
| 182 size_.height(), | |
| 183 DataFormat(internalformat_), | |
| 184 DataType(internalformat_), | |
| 185 shared_memory_->memory()); | |
| 186 } | |
| 187 | |
| 188 glEGLImageTargetTexture2DOES(target, egl_image_); | |
| 189 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | |
| 190 | |
| 191 shared_memory_->Unmap(); | |
| 192 return true; | |
| 193 } | |
| 194 #endif | |
| 195 | |
| 196 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); | |
| 197 glTexImage2D(target, | |
| 198 0, // mip level | |
| 199 TextureFormat(internalformat_), | |
| 200 size_.width(), | |
| 201 size_.height(), | |
| 202 0, // border | |
| 203 DataFormat(internalformat_), | |
| 204 DataType(internalformat_), | |
| 205 shared_memory_->memory()); | |
| 206 | |
| 207 shared_memory_->Unmap(); | |
| 208 return true; | |
| 209 } | |
| 210 | |
| 211 } // namespace gfx | |
| OLD | NEW |