| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/texture_definition.h" | 5 #include "gpu/command_buffer/service/texture_definition.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 | 8 |
| 9 #include "base/memory/linked_ptr.h" | 9 #include "base/memory/linked_ptr.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/synchronization/lock.h" | 11 #include "base/synchronization/lock.h" |
| 12 #include "gpu/command_buffer/service/texture_manager.h" | 12 #include "gpu/command_buffer/service/texture_manager.h" |
| 13 #include "ui/gl/gl_image.h" | 13 #include "ui/gl/gl_image.h" |
| 14 #include "ui/gl/gl_implementation.h" | 14 #include "ui/gl/gl_implementation.h" |
| 15 #include "ui/gl/scoped_binders.h" | 15 #include "ui/gl/scoped_binders.h" |
| 16 | 16 |
| 17 #if !defined(OS_MACOSX) | 17 #if !defined(OS_MACOSX) |
| 18 #include "ui/gl/gl_fence_egl.h" | |
| 19 #include "ui/gl/gl_surface_egl.h" | 18 #include "ui/gl/gl_surface_egl.h" |
| 20 #endif | 19 #endif |
| 21 | 20 |
| 22 namespace gpu { | 21 namespace gpu { |
| 23 namespace gles2 { | 22 namespace gles2 { |
| 24 | 23 |
| 25 namespace { | 24 namespace { |
| 26 | 25 |
| 27 class GLImageSync : public gfx::GLImage { | 26 class GLImageSync : public gfx::GLImage { |
| 28 public: | 27 public: |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 | 80 |
| 82 void GLImageSync::ReleaseTexImage(unsigned target) { | 81 void GLImageSync::ReleaseTexImage(unsigned target) { |
| 83 NOTREACHED(); | 82 NOTREACHED(); |
| 84 } | 83 } |
| 85 | 84 |
| 86 bool GLImageSync::CopyTexImage(unsigned target) { | 85 bool GLImageSync::CopyTexImage(unsigned target) { |
| 87 return false; | 86 return false; |
| 88 } | 87 } |
| 89 | 88 |
| 90 void GLImageSync::WillUseTexImage() { | 89 void GLImageSync::WillUseTexImage() { |
| 91 if (buffer_.get()) | |
| 92 buffer_->WillRead(this); | |
| 93 } | 90 } |
| 94 | 91 |
| 95 void GLImageSync::DidUseTexImage() { | 92 void GLImageSync::DidUseTexImage() { |
| 96 if (buffer_.get()) | |
| 97 buffer_->DidRead(this); | |
| 98 } | 93 } |
| 99 | 94 |
| 100 void GLImageSync::WillModifyTexImage() { | 95 void GLImageSync::WillModifyTexImage() { |
| 101 if (buffer_.get()) | |
| 102 buffer_->WillWrite(this); | |
| 103 } | 96 } |
| 104 | 97 |
| 105 void GLImageSync::DidModifyTexImage() { | 98 void GLImageSync::DidModifyTexImage() { |
| 106 if (buffer_.get()) | |
| 107 buffer_->DidWrite(this); | |
| 108 } | 99 } |
| 109 | 100 |
| 110 bool GLImageSync::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 101 bool GLImageSync::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
| 111 int z_order, | 102 int z_order, |
| 112 gfx::OverlayTransform transform, | 103 gfx::OverlayTransform transform, |
| 113 const gfx::Rect& bounds_rect, | 104 const gfx::Rect& bounds_rect, |
| 114 const gfx::RectF& crop_rect) { | 105 const gfx::RectF& crop_rect) { |
| 115 NOTREACHED(); | 106 NOTREACHED(); |
| 116 return false; | 107 return false; |
| 117 } | 108 } |
| 118 | 109 |
| 119 #if !defined(OS_MACOSX) | 110 #if !defined(OS_MACOSX) |
| 120 class NativeImageBufferEGL : public NativeImageBuffer { | 111 class NativeImageBufferEGL : public NativeImageBuffer { |
| 121 public: | 112 public: |
| 122 static scoped_refptr<NativeImageBufferEGL> Create(GLuint texture_id); | 113 static scoped_refptr<NativeImageBufferEGL> Create(GLuint texture_id); |
| 123 | 114 |
| 124 private: | 115 private: |
| 125 NativeImageBufferEGL(EGLDisplay display, EGLImageKHR image); | 116 NativeImageBufferEGL(EGLDisplay display, EGLImageKHR image); |
| 126 virtual ~NativeImageBufferEGL(); | 117 virtual ~NativeImageBufferEGL(); |
| 127 virtual void AddClient(gfx::GLImage* client) override; | 118 virtual void AddClient(gfx::GLImage* client) override; |
| 128 virtual void RemoveClient(gfx::GLImage* client) override; | 119 virtual void RemoveClient(gfx::GLImage* client) override; |
| 129 virtual bool IsClient(gfx::GLImage* client) override; | 120 virtual bool IsClient(gfx::GLImage* client) override; |
| 130 virtual void BindToTexture(GLenum target) override; | 121 virtual void BindToTexture(GLenum target) override; |
| 131 virtual void WillRead(gfx::GLImage* client) override; | |
| 132 virtual void WillWrite(gfx::GLImage* client) override; | |
| 133 virtual void DidRead(gfx::GLImage* client) override; | |
| 134 virtual void DidWrite(gfx::GLImage* client) override; | |
| 135 | 122 |
| 136 EGLDisplay egl_display_; | 123 EGLDisplay egl_display_; |
| 137 EGLImageKHR egl_image_; | 124 EGLImageKHR egl_image_; |
| 138 | 125 |
| 139 base::Lock lock_; | 126 base::Lock lock_; |
| 140 | 127 |
| 141 struct ClientInfo { | 128 struct ClientInfo { |
| 142 ClientInfo(gfx::GLImage* client); | 129 ClientInfo(gfx::GLImage* client); |
| 143 ~ClientInfo(); | 130 ~ClientInfo(); |
| 144 | 131 |
| 145 gfx::GLImage* client; | 132 gfx::GLImage* client; |
| 146 bool needs_wait_before_read; | 133 bool needs_wait_before_read; |
| 147 linked_ptr<gfx::GLFence> read_fence; | |
| 148 }; | 134 }; |
| 149 std::list<ClientInfo> client_infos_; | 135 std::list<ClientInfo> client_infos_; |
| 150 scoped_ptr<gfx::GLFence> write_fence_; | |
| 151 gfx::GLImage* write_client_; | 136 gfx::GLImage* write_client_; |
| 152 | 137 |
| 153 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL); | 138 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL); |
| 154 }; | 139 }; |
| 155 | 140 |
| 156 scoped_refptr<NativeImageBufferEGL> NativeImageBufferEGL::Create( | 141 scoped_refptr<NativeImageBufferEGL> NativeImageBufferEGL::Create( |
| 157 GLuint texture_id) { | 142 GLuint texture_id) { |
| 158 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 143 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); |
| 159 EGLContext egl_context = eglGetCurrentContext(); | 144 EGLContext egl_context = eglGetCurrentContext(); |
| 160 | 145 |
| 161 DCHECK_NE(EGL_NO_CONTEXT, egl_context); | 146 DCHECK_NE(EGL_NO_CONTEXT, egl_context); |
| 162 DCHECK_NE(EGL_NO_DISPLAY, egl_display); | 147 DCHECK_NE(EGL_NO_DISPLAY, egl_display); |
| 163 DCHECK(glIsTexture(texture_id)); | 148 DCHECK(glIsTexture(texture_id)); |
| 164 | 149 |
| 165 DCHECK(gfx::g_driver_egl.ext.b_EGL_KHR_image_base && | 150 DCHECK(gfx::g_driver_egl.ext.b_EGL_KHR_image_base && |
| 166 gfx::g_driver_egl.ext.b_EGL_KHR_gl_texture_2D_image && | 151 gfx::g_driver_egl.ext.b_EGL_KHR_gl_texture_2D_image && |
| 167 gfx::g_driver_gl.ext.b_GL_OES_EGL_image && | 152 gfx::g_driver_gl.ext.b_GL_OES_EGL_image); |
| 168 gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync); | |
| 169 | 153 |
| 170 const EGLint egl_attrib_list[] = { | 154 const EGLint egl_attrib_list[] = { |
| 171 EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 155 EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
| 172 EGLClientBuffer egl_buffer = reinterpret_cast<EGLClientBuffer>(texture_id); | 156 EGLClientBuffer egl_buffer = reinterpret_cast<EGLClientBuffer>(texture_id); |
| 173 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; // TODO | 157 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; // TODO |
| 174 | 158 |
| 175 EGLImageKHR egl_image = eglCreateImageKHR( | 159 EGLImageKHR egl_image = eglCreateImageKHR( |
| 176 egl_display, egl_context, egl_target, egl_buffer, egl_attrib_list); | 160 egl_display, egl_context, egl_target, egl_buffer, egl_attrib_list); |
| 177 | 161 |
| 178 if (egl_image == EGL_NO_IMAGE_KHR) | 162 if (egl_image == EGL_NO_IMAGE_KHR) |
| 179 return NULL; | 163 return NULL; |
| 180 | 164 |
| 181 return new NativeImageBufferEGL(egl_display, egl_image); | 165 return new NativeImageBufferEGL(egl_display, egl_image); |
| 182 } | 166 } |
| 183 | 167 |
| 184 NativeImageBufferEGL::ClientInfo::ClientInfo(gfx::GLImage* client) | 168 NativeImageBufferEGL::ClientInfo::ClientInfo(gfx::GLImage* client) |
| 185 : client(client), needs_wait_before_read(true) {} | 169 : client(client), needs_wait_before_read(true) {} |
| 186 | 170 |
| 187 NativeImageBufferEGL::ClientInfo::~ClientInfo() {} | 171 NativeImageBufferEGL::ClientInfo::~ClientInfo() {} |
| 188 | 172 |
| 189 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display, | 173 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display, |
| 190 EGLImageKHR image) | 174 EGLImageKHR image) |
| 191 : NativeImageBuffer(), | 175 : NativeImageBuffer(), |
| 192 egl_display_(display), | 176 egl_display_(display), |
| 193 egl_image_(image), | 177 egl_image_(image), |
| 194 write_fence_(new gfx::GLFenceEGL(true)), | |
| 195 write_client_(NULL) { | 178 write_client_(NULL) { |
| 196 DCHECK(egl_display_ != EGL_NO_DISPLAY); | 179 DCHECK(egl_display_ != EGL_NO_DISPLAY); |
| 197 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); | 180 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); |
| 198 } | 181 } |
| 199 | 182 |
| 200 NativeImageBufferEGL::~NativeImageBufferEGL() { | 183 NativeImageBufferEGL::~NativeImageBufferEGL() { |
| 201 DCHECK(client_infos_.empty()); | 184 DCHECK(client_infos_.empty()); |
| 202 if (egl_image_ != EGL_NO_IMAGE_KHR) | 185 if (egl_image_ != EGL_NO_IMAGE_KHR) |
| 203 eglDestroyImageKHR(egl_display_, egl_image_); | 186 eglDestroyImageKHR(egl_display_, egl_image_); |
| 204 } | 187 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 234 return false; | 217 return false; |
| 235 } | 218 } |
| 236 | 219 |
| 237 void NativeImageBufferEGL::BindToTexture(GLenum target) { | 220 void NativeImageBufferEGL::BindToTexture(GLenum target) { |
| 238 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); | 221 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); |
| 239 glEGLImageTargetTexture2DOES(target, egl_image_); | 222 glEGLImageTargetTexture2DOES(target, egl_image_); |
| 240 DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError()); | 223 DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError()); |
| 241 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 224 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 242 } | 225 } |
| 243 | 226 |
| 244 void NativeImageBufferEGL::WillRead(gfx::GLImage* client) { | |
| 245 base::AutoLock lock(lock_); | |
| 246 if (!write_fence_.get() || write_client_ == client) | |
| 247 return; | |
| 248 | |
| 249 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); | |
| 250 it != client_infos_.end(); | |
| 251 it++) { | |
| 252 if (it->client == client) { | |
| 253 if (it->needs_wait_before_read) { | |
| 254 it->needs_wait_before_read = false; | |
| 255 write_fence_->ServerWait(); | |
| 256 } | |
| 257 return; | |
| 258 } | |
| 259 } | |
| 260 NOTREACHED(); | |
| 261 } | |
| 262 | |
| 263 void NativeImageBufferEGL::WillWrite(gfx::GLImage* client) { | |
| 264 base::AutoLock lock(lock_); | |
| 265 if (write_client_ != client) | |
| 266 write_fence_->ServerWait(); | |
| 267 | |
| 268 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); | |
| 269 it != client_infos_.end(); | |
| 270 it++) { | |
| 271 if (it->read_fence.get() && it->client != client) | |
| 272 it->read_fence->ServerWait(); | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 void NativeImageBufferEGL::DidRead(gfx::GLImage* client) { | |
| 277 base::AutoLock lock(lock_); | |
| 278 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); | |
| 279 it != client_infos_.end(); | |
| 280 it++) { | |
| 281 if (it->client == client) { | |
| 282 it->read_fence = make_linked_ptr(new gfx::GLFenceEGL(true)); | |
| 283 return; | |
| 284 } | |
| 285 } | |
| 286 NOTREACHED(); | |
| 287 } | |
| 288 | |
| 289 void NativeImageBufferEGL::DidWrite(gfx::GLImage* client) { | |
| 290 base::AutoLock lock(lock_); | |
| 291 // Sharing semantics require the client to flush in order to make changes | |
| 292 // visible to other clients. | |
| 293 write_fence_.reset(new gfx::GLFenceEGL(false)); | |
| 294 write_client_ = client; | |
| 295 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); | |
| 296 it != client_infos_.end(); | |
| 297 it++) { | |
| 298 it->needs_wait_before_read = true; | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 #endif | 227 #endif |
| 303 | 228 |
| 304 class NativeImageBufferStub : public NativeImageBuffer { | 229 class NativeImageBufferStub : public NativeImageBuffer { |
| 305 public: | 230 public: |
| 306 NativeImageBufferStub() : NativeImageBuffer() {} | 231 NativeImageBufferStub() : NativeImageBuffer() {} |
| 307 | 232 |
| 308 private: | 233 private: |
| 309 ~NativeImageBufferStub() override {} | 234 ~NativeImageBufferStub() override {} |
| 310 void AddClient(gfx::GLImage* client) override {} | 235 void AddClient(gfx::GLImage* client) override {} |
| 311 void RemoveClient(gfx::GLImage* client) override {} | 236 void RemoveClient(gfx::GLImage* client) override {} |
| 312 bool IsClient(gfx::GLImage* client) override { return true; } | 237 bool IsClient(gfx::GLImage* client) override { return true; } |
| 313 void BindToTexture(GLenum target) override {} | 238 void BindToTexture(GLenum target) override {} |
| 314 void WillRead(gfx::GLImage* client) override {} | |
| 315 void WillWrite(gfx::GLImage* client) override {} | |
| 316 void DidRead(gfx::GLImage* client) override {} | |
| 317 void DidWrite(gfx::GLImage* client) override {} | |
| 318 | 239 |
| 319 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub); | 240 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub); |
| 320 }; | 241 }; |
| 321 | 242 |
| 322 } // anonymous namespace | 243 } // anonymous namespace |
| 323 | 244 |
| 324 // static | 245 // static |
| 325 scoped_refptr<NativeImageBuffer> NativeImageBuffer::Create(GLuint texture_id) { | 246 scoped_refptr<NativeImageBuffer> NativeImageBuffer::Create(GLuint texture_id) { |
| 326 switch (gfx::GetGLImplementation()) { | 247 switch (gfx::GetGLImplementation()) { |
| 327 #if !defined(OS_MACOSX) | 248 #if !defined(OS_MACOSX) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 | 409 |
| 489 // All structural changes should have orphaned the texture. | 410 // All structural changes should have orphaned the texture. |
| 490 if (image_buffer_.get() && !texture->GetLevelImage(texture->target(), 0)) | 411 if (image_buffer_.get() && !texture->GetLevelImage(texture->target(), 0)) |
| 491 return false; | 412 return false; |
| 492 | 413 |
| 493 return true; | 414 return true; |
| 494 } | 415 } |
| 495 | 416 |
| 496 } // namespace gles2 | 417 } // namespace gles2 |
| 497 } // namespace gpu | 418 } // namespace gpu |
| OLD | NEW |