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/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/memory/linked_ptr.h" | 10 #include "base/memory/linked_ptr.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
13 #include "base/threading/thread_local.h" | 13 #include "base/threading/thread_local.h" |
14 #include "gpu/command_buffer/service/texture_manager.h" | 14 #include "gpu/command_buffer/service/texture_manager.h" |
15 #include "ui/gl/gl_image.h" | 15 #include "ui/gl/gl_image.h" |
16 #include "ui/gl/gl_implementation.h" | 16 #include "ui/gl/gl_implementation.h" |
17 #include "ui/gl/scoped_binders.h" | 17 #include "ui/gl/scoped_binders.h" |
18 | 18 |
19 #if !defined(OS_MACOSX) | 19 #if !defined(OS_MACOSX) |
20 #include "ui/gl/gl_surface_egl.h" | 20 #include "ui/gl/gl_surface_egl.h" |
21 #endif | 21 #endif |
22 | 22 |
23 namespace gpu { | 23 namespace gpu { |
24 namespace gles2 { | 24 namespace gles2 { |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 class GLImageSync : public gfx::GLImage { | 28 class GLImageSync : public gl::GLImage { |
29 public: | 29 public: |
30 explicit GLImageSync(const scoped_refptr<NativeImageBuffer>& buffer, | 30 explicit GLImageSync(const scoped_refptr<NativeImageBuffer>& buffer, |
31 const gfx::Size& size); | 31 const gfx::Size& size); |
32 | 32 |
33 // Implement GLImage. | 33 // Implement GLImage. |
34 void Destroy(bool have_context) override; | 34 void Destroy(bool have_context) override; |
35 gfx::Size GetSize() override; | 35 gfx::Size GetSize() override; |
36 unsigned GetInternalFormat() override; | 36 unsigned GetInternalFormat() override; |
37 bool BindTexImage(unsigned target) override; | 37 bool BindTexImage(unsigned target) override; |
38 void ReleaseTexImage(unsigned target) override; | 38 void ReleaseTexImage(unsigned target) override; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 } | 117 } |
118 | 118 |
119 #if !defined(OS_MACOSX) | 119 #if !defined(OS_MACOSX) |
120 class NativeImageBufferEGL : public NativeImageBuffer { | 120 class NativeImageBufferEGL : public NativeImageBuffer { |
121 public: | 121 public: |
122 static scoped_refptr<NativeImageBufferEGL> Create(GLuint texture_id); | 122 static scoped_refptr<NativeImageBufferEGL> Create(GLuint texture_id); |
123 | 123 |
124 private: | 124 private: |
125 NativeImageBufferEGL(EGLDisplay display, EGLImageKHR image); | 125 NativeImageBufferEGL(EGLDisplay display, EGLImageKHR image); |
126 ~NativeImageBufferEGL() override; | 126 ~NativeImageBufferEGL() override; |
127 void AddClient(gfx::GLImage* client) override; | 127 void AddClient(gl::GLImage* client) override; |
128 void RemoveClient(gfx::GLImage* client) override; | 128 void RemoveClient(gl::GLImage* client) override; |
129 bool IsClient(gfx::GLImage* client) override; | 129 bool IsClient(gl::GLImage* client) override; |
130 void BindToTexture(GLenum target) const override; | 130 void BindToTexture(GLenum target) const override; |
131 | 131 |
132 const EGLDisplay egl_display_; | 132 const EGLDisplay egl_display_; |
133 const EGLImageKHR egl_image_; | 133 const EGLImageKHR egl_image_; |
134 | 134 |
135 base::Lock lock_; | 135 base::Lock lock_; |
136 | 136 |
137 struct ClientInfo { | 137 struct ClientInfo { |
138 explicit ClientInfo(gfx::GLImage* client); | 138 explicit ClientInfo(gl::GLImage* client); |
139 ~ClientInfo(); | 139 ~ClientInfo(); |
140 | 140 |
141 gfx::GLImage* client; | 141 gl::GLImage* client; |
142 bool needs_wait_before_read; | 142 bool needs_wait_before_read; |
143 }; | 143 }; |
144 std::list<ClientInfo> client_infos_; | 144 std::list<ClientInfo> client_infos_; |
145 gfx::GLImage* write_client_; | 145 gl::GLImage* write_client_; |
146 | 146 |
147 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL); | 147 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL); |
148 }; | 148 }; |
149 | 149 |
150 scoped_refptr<NativeImageBufferEGL> NativeImageBufferEGL::Create( | 150 scoped_refptr<NativeImageBufferEGL> NativeImageBufferEGL::Create( |
151 GLuint texture_id) { | 151 GLuint texture_id) { |
152 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); | 152 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay(); |
153 EGLContext egl_context = eglGetCurrentContext(); | 153 EGLContext egl_context = eglGetCurrentContext(); |
154 | 154 |
155 DCHECK_NE(EGL_NO_CONTEXT, egl_context); | 155 DCHECK_NE(EGL_NO_CONTEXT, egl_context); |
(...skipping 14 matching lines...) Expand all Loading... |
170 | 170 |
171 if (egl_image == EGL_NO_IMAGE_KHR) { | 171 if (egl_image == EGL_NO_IMAGE_KHR) { |
172 LOG(ERROR) << "eglCreateImageKHR for cross-thread sharing failed: 0x" | 172 LOG(ERROR) << "eglCreateImageKHR for cross-thread sharing failed: 0x" |
173 << std::hex << eglGetError(); | 173 << std::hex << eglGetError(); |
174 return NULL; | 174 return NULL; |
175 } | 175 } |
176 | 176 |
177 return new NativeImageBufferEGL(egl_display, egl_image); | 177 return new NativeImageBufferEGL(egl_display, egl_image); |
178 } | 178 } |
179 | 179 |
180 NativeImageBufferEGL::ClientInfo::ClientInfo(gfx::GLImage* client) | 180 NativeImageBufferEGL::ClientInfo::ClientInfo(gl::GLImage* client) |
181 : client(client), needs_wait_before_read(true) {} | 181 : client(client), needs_wait_before_read(true) {} |
182 | 182 |
183 NativeImageBufferEGL::ClientInfo::~ClientInfo() {} | 183 NativeImageBufferEGL::ClientInfo::~ClientInfo() {} |
184 | 184 |
185 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display, | 185 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display, |
186 EGLImageKHR image) | 186 EGLImageKHR image) |
187 : NativeImageBuffer(), | 187 : NativeImageBuffer(), |
188 egl_display_(display), | 188 egl_display_(display), |
189 egl_image_(image), | 189 egl_image_(image), |
190 write_client_(NULL) { | 190 write_client_(NULL) { |
191 DCHECK(egl_display_ != EGL_NO_DISPLAY); | 191 DCHECK(egl_display_ != EGL_NO_DISPLAY); |
192 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); | 192 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); |
193 } | 193 } |
194 | 194 |
195 NativeImageBufferEGL::~NativeImageBufferEGL() { | 195 NativeImageBufferEGL::~NativeImageBufferEGL() { |
196 DCHECK(client_infos_.empty()); | 196 DCHECK(client_infos_.empty()); |
197 if (egl_image_ != EGL_NO_IMAGE_KHR) | 197 if (egl_image_ != EGL_NO_IMAGE_KHR) |
198 eglDestroyImageKHR(egl_display_, egl_image_); | 198 eglDestroyImageKHR(egl_display_, egl_image_); |
199 } | 199 } |
200 | 200 |
201 void NativeImageBufferEGL::AddClient(gfx::GLImage* client) { | 201 void NativeImageBufferEGL::AddClient(gl::GLImage* client) { |
202 base::AutoLock lock(lock_); | 202 base::AutoLock lock(lock_); |
203 client_infos_.push_back(ClientInfo(client)); | 203 client_infos_.push_back(ClientInfo(client)); |
204 } | 204 } |
205 | 205 |
206 void NativeImageBufferEGL::RemoveClient(gfx::GLImage* client) { | 206 void NativeImageBufferEGL::RemoveClient(gl::GLImage* client) { |
207 base::AutoLock lock(lock_); | 207 base::AutoLock lock(lock_); |
208 if (write_client_ == client) | 208 if (write_client_ == client) |
209 write_client_ = NULL; | 209 write_client_ = NULL; |
210 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); | 210 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); |
211 it != client_infos_.end(); | 211 it != client_infos_.end(); |
212 it++) { | 212 it++) { |
213 if (it->client == client) { | 213 if (it->client == client) { |
214 client_infos_.erase(it); | 214 client_infos_.erase(it); |
215 return; | 215 return; |
216 } | 216 } |
217 } | 217 } |
218 NOTREACHED(); | 218 NOTREACHED(); |
219 } | 219 } |
220 | 220 |
221 bool NativeImageBufferEGL::IsClient(gfx::GLImage* client) { | 221 bool NativeImageBufferEGL::IsClient(gl::GLImage* client) { |
222 base::AutoLock lock(lock_); | 222 base::AutoLock lock(lock_); |
223 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); | 223 for (std::list<ClientInfo>::iterator it = client_infos_.begin(); |
224 it != client_infos_.end(); | 224 it != client_infos_.end(); |
225 it++) { | 225 it++) { |
226 if (it->client == client) | 226 if (it->client == client) |
227 return true; | 227 return true; |
228 } | 228 } |
229 return false; | 229 return false; |
230 } | 230 } |
231 | 231 |
232 void NativeImageBufferEGL::BindToTexture(GLenum target) const { | 232 void NativeImageBufferEGL::BindToTexture(GLenum target) const { |
233 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); | 233 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR); |
234 glEGLImageTargetTexture2DOES(target, egl_image_); | 234 glEGLImageTargetTexture2DOES(target, egl_image_); |
235 DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError()); | 235 DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError()); |
236 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 236 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
237 } | 237 } |
238 | 238 |
239 #endif | 239 #endif |
240 | 240 |
241 class NativeImageBufferStub : public NativeImageBuffer { | 241 class NativeImageBufferStub : public NativeImageBuffer { |
242 public: | 242 public: |
243 NativeImageBufferStub() : NativeImageBuffer() {} | 243 NativeImageBufferStub() : NativeImageBuffer() {} |
244 | 244 |
245 private: | 245 private: |
246 ~NativeImageBufferStub() override {} | 246 ~NativeImageBufferStub() override {} |
247 void AddClient(gfx::GLImage* client) override {} | 247 void AddClient(gl::GLImage* client) override {} |
248 void RemoveClient(gfx::GLImage* client) override {} | 248 void RemoveClient(gl::GLImage* client) override {} |
249 bool IsClient(gfx::GLImage* client) override { return true; } | 249 bool IsClient(gl::GLImage* client) override { return true; } |
250 void BindToTexture(GLenum target) const override {} | 250 void BindToTexture(GLenum target) const override {} |
251 | 251 |
252 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub); | 252 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub); |
253 }; | 253 }; |
254 | 254 |
255 bool g_avoid_egl_target_texture_reuse = false; | 255 bool g_avoid_egl_target_texture_reuse = false; |
256 | 256 |
257 } // anonymous namespace | 257 } // anonymous namespace |
258 | 258 |
259 // static | 259 // static |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 immutable_(texture->IsImmutable()), | 335 immutable_(texture->IsImmutable()), |
336 defined_(texture->IsDefined()) { | 336 defined_(texture->IsDefined()) { |
337 DCHECK_IMPLIES(image_buffer_.get(), defined_); | 337 DCHECK_IMPLIES(image_buffer_.get(), defined_); |
338 if (!image_buffer_.get() && defined_) { | 338 if (!image_buffer_.get() && defined_) { |
339 image_buffer_ = NativeImageBuffer::Create(texture->service_id()); | 339 image_buffer_ = NativeImageBuffer::Create(texture->service_id()); |
340 DCHECK(image_buffer_.get()); | 340 DCHECK(image_buffer_.get()); |
341 } | 341 } |
342 | 342 |
343 const Texture::FaceInfo& first_face = texture->face_infos_[0]; | 343 const Texture::FaceInfo& first_face = texture->face_infos_[0]; |
344 if (image_buffer_.get()) { | 344 if (image_buffer_.get()) { |
345 scoped_refptr<gfx::GLImage> gl_image( | 345 scoped_refptr<gl::GLImage> gl_image(new GLImageSync( |
346 new GLImageSync(image_buffer_, | 346 image_buffer_, gfx::Size(first_face.level_infos[0].width, |
347 gfx::Size(first_face.level_infos[0].width, | 347 first_face.level_infos[0].height))); |
348 first_face.level_infos[0].height))); | |
349 texture->SetLevelImage(target_, 0, gl_image.get(), Texture::BOUND); | 348 texture->SetLevelImage(target_, 0, gl_image.get(), Texture::BOUND); |
350 } | 349 } |
351 | 350 |
352 const Texture::LevelInfo& level = first_face.level_infos[0]; | 351 const Texture::LevelInfo& level = first_face.level_infos[0]; |
353 level_info_ = LevelInfo(level.target, level.internal_format, level.width, | 352 level_info_ = LevelInfo(level.target, level.internal_format, level.width, |
354 level.height, level.depth, level.border, level.format, | 353 level.height, level.depth, level.border, level.format, |
355 level.type, level.cleared_rect); | 354 level.type, level.cleared_rect); |
356 } | 355 } |
357 | 356 |
358 TextureDefinition::~TextureDefinition() { | 357 TextureDefinition::~TextureDefinition() { |
(...skipping 10 matching lines...) Expand all Loading... |
369 } | 368 } |
370 | 369 |
371 void TextureDefinition::UpdateTextureInternal(Texture* texture) const { | 370 void TextureDefinition::UpdateTextureInternal(Texture* texture) const { |
372 gfx::ScopedTextureBinder texture_binder(target_, texture->service_id()); | 371 gfx::ScopedTextureBinder texture_binder(target_, texture->service_id()); |
373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_); | 372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_); |
374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_); | 373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_); |
375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_); | 374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_); |
376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_); | 375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_); |
377 | 376 |
378 if (image_buffer_.get()) { | 377 if (image_buffer_.get()) { |
379 gfx::GLImage* existing_image = texture->GetLevelImage(target_, 0); | 378 gl::GLImage* existing_image = texture->GetLevelImage(target_, 0); |
380 // Don't need to re-bind if already bound before. | 379 // Don't need to re-bind if already bound before. |
381 if (!existing_image || !image_buffer_->IsClient(existing_image)) { | 380 if (!existing_image || !image_buffer_->IsClient(existing_image)) { |
382 image_buffer_->BindToTexture(target_); | 381 image_buffer_->BindToTexture(target_); |
383 } | 382 } |
384 } | 383 } |
385 | 384 |
386 if (defined_) { | 385 if (defined_) { |
387 texture->face_infos_.resize(1); | 386 texture->face_infos_.resize(1); |
388 texture->face_infos_[0].level_infos.resize(1); | 387 texture->face_infos_[0].level_infos.resize(1); |
389 texture->SetLevelInfo(NULL, level_info_.target, 0, | 388 texture->SetLevelInfo(NULL, level_info_.target, 0, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 return true; | 454 return true; |
456 } | 455 } |
457 | 456 |
458 bool TextureDefinition::SafeToRenderFrom() const { | 457 bool TextureDefinition::SafeToRenderFrom() const { |
459 return level_info_.cleared_rect.Contains( | 458 return level_info_.cleared_rect.Contains( |
460 gfx::Rect(level_info_.width, level_info_.height)); | 459 gfx::Rect(level_info_.width, level_info_.height)); |
461 } | 460 } |
462 | 461 |
463 } // namespace gles2 | 462 } // namespace gles2 |
464 } // namespace gpu | 463 } // namespace gpu |
OLD | NEW |