| 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" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 gfx::g_driver_gl.ext.b_GL_OES_EGL_image); | 152 gfx::g_driver_gl.ext.b_GL_OES_EGL_image); |
| 153 | 153 |
| 154 const EGLint egl_attrib_list[] = { | 154 const EGLint egl_attrib_list[] = { |
| 155 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}; |
| 156 EGLClientBuffer egl_buffer = reinterpret_cast<EGLClientBuffer>(texture_id); | 156 EGLClientBuffer egl_buffer = reinterpret_cast<EGLClientBuffer>(texture_id); |
| 157 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; // TODO | 157 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; // TODO |
| 158 | 158 |
| 159 EGLImageKHR egl_image = eglCreateImageKHR( | 159 EGLImageKHR egl_image = eglCreateImageKHR( |
| 160 egl_display, egl_context, egl_target, egl_buffer, egl_attrib_list); | 160 egl_display, egl_context, egl_target, egl_buffer, egl_attrib_list); |
| 161 | 161 |
| 162 if (egl_image == EGL_NO_IMAGE_KHR) | 162 if (egl_image == EGL_NO_IMAGE_KHR) { |
| 163 LOG(ERROR) << "eglCreateImageKHR for cross-thread sharing failed: 0x" |
| 164 << std::hex << eglGetError(); |
| 163 return NULL; | 165 return NULL; |
| 166 } |
| 164 | 167 |
| 165 return new NativeImageBufferEGL(egl_display, egl_image); | 168 return new NativeImageBufferEGL(egl_display, egl_image); |
| 166 } | 169 } |
| 167 | 170 |
| 168 NativeImageBufferEGL::ClientInfo::ClientInfo(gfx::GLImage* client) | 171 NativeImageBufferEGL::ClientInfo::ClientInfo(gfx::GLImage* client) |
| 169 : client(client), needs_wait_before_read(true) {} | 172 : client(client), needs_wait_before_read(true) {} |
| 170 | 173 |
| 171 NativeImageBufferEGL::ClientInfo::~ClientInfo() {} | 174 NativeImageBufferEGL::ClientInfo::~ClientInfo() {} |
| 172 | 175 |
| 173 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display, | 176 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display, |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 return NativeImageBufferEGL::Create(texture_id); | 253 return NativeImageBufferEGL::Create(texture_id); |
| 251 #endif | 254 #endif |
| 252 case gfx::kGLImplementationMockGL: | 255 case gfx::kGLImplementationMockGL: |
| 253 return new NativeImageBufferStub; | 256 return new NativeImageBufferStub; |
| 254 default: | 257 default: |
| 255 NOTREACHED(); | 258 NOTREACHED(); |
| 256 return NULL; | 259 return NULL; |
| 257 } | 260 } |
| 258 } | 261 } |
| 259 | 262 |
| 263 TextureDefinition::LevelInfo::LevelInfo() |
| 264 : target(0), |
| 265 internal_format(0), |
| 266 width(0), |
| 267 height(0), |
| 268 depth(0), |
| 269 border(0), |
| 270 format(0), |
| 271 type(0), |
| 272 cleared(false) { |
| 273 } |
| 274 |
| 260 TextureDefinition::LevelInfo::LevelInfo(GLenum target, | 275 TextureDefinition::LevelInfo::LevelInfo(GLenum target, |
| 261 GLenum internal_format, | 276 GLenum internal_format, |
| 262 GLsizei width, | 277 GLsizei width, |
| 263 GLsizei height, | 278 GLsizei height, |
| 264 GLsizei depth, | 279 GLsizei depth, |
| 265 GLint border, | 280 GLint border, |
| 266 GLenum format, | 281 GLenum format, |
| 267 GLenum type, | 282 GLenum type, |
| 268 bool cleared) | 283 bool cleared) |
| 269 : target(target), | 284 : target(target), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 288 usage_(0), | 303 usage_(0), |
| 289 immutable_(true) { | 304 immutable_(true) { |
| 290 } | 305 } |
| 291 | 306 |
| 292 TextureDefinition::TextureDefinition( | 307 TextureDefinition::TextureDefinition( |
| 293 Texture* texture, | 308 Texture* texture, |
| 294 unsigned int version, | 309 unsigned int version, |
| 295 const scoped_refptr<NativeImageBuffer>& image_buffer) | 310 const scoped_refptr<NativeImageBuffer>& image_buffer) |
| 296 : version_(version), | 311 : version_(version), |
| 297 target_(texture->target()), | 312 target_(texture->target()), |
| 298 image_buffer_(image_buffer.get() | 313 image_buffer_(image_buffer), |
| 299 ? image_buffer | |
| 300 : NativeImageBuffer::Create(texture->service_id())), | |
| 301 min_filter_(texture->min_filter()), | 314 min_filter_(texture->min_filter()), |
| 302 mag_filter_(texture->mag_filter()), | 315 mag_filter_(texture->mag_filter()), |
| 303 wrap_s_(texture->wrap_s()), | 316 wrap_s_(texture->wrap_s()), |
| 304 wrap_t_(texture->wrap_t()), | 317 wrap_t_(texture->wrap_t()), |
| 305 usage_(texture->usage()), | 318 usage_(texture->usage()), |
| 306 immutable_(texture->IsImmutable()) { | 319 immutable_(texture->IsImmutable()), |
| 307 // TODO | 320 defined_(texture->IsDefined()) { |
| 308 DCHECK(!texture->face_infos_.empty()); | 321 DCHECK_IMPLIES(image_buffer_.get(), defined_); |
| 309 DCHECK(!texture->face_infos_[0].level_infos.empty()); | 322 if (!image_buffer_.get() && defined_) { |
| 310 DCHECK(!texture->NeedsMips()); | 323 image_buffer_ = NativeImageBuffer::Create(texture->service_id()); |
| 311 DCHECK(texture->face_infos_[0].level_infos[0].width); | 324 DCHECK(image_buffer_.get()); |
| 312 DCHECK(texture->face_infos_[0].level_infos[0].height); | 325 } |
| 313 | 326 |
| 314 const Texture::FaceInfo& first_face = texture->face_infos_[0]; | 327 const Texture::FaceInfo& first_face = texture->face_infos_[0]; |
| 315 scoped_refptr<gfx::GLImage> gl_image( | 328 if (image_buffer_.get()) { |
| 316 new GLImageSync(image_buffer_, | 329 scoped_refptr<gfx::GLImage> gl_image( |
| 317 gfx::Size(first_face.level_infos[0].width, | 330 new GLImageSync(image_buffer_, |
| 318 first_face.level_infos[0].height))); | 331 gfx::Size(first_face.level_infos[0].width, |
| 319 texture->SetLevelImage(NULL, target_, 0, gl_image.get()); | 332 first_face.level_infos[0].height))); |
| 333 texture->SetLevelImage(NULL, target_, 0, gl_image.get()); |
| 334 } |
| 320 | 335 |
| 321 // TODO: all levels | |
| 322 level_infos_.clear(); | |
| 323 const Texture::LevelInfo& level = first_face.level_infos[0]; | 336 const Texture::LevelInfo& level = first_face.level_infos[0]; |
| 324 LevelInfo info(level.target, | 337 level_info_ = LevelInfo(level.target, level.internal_format, level.width, |
| 325 level.internal_format, | 338 level.height, level.depth, level.border, level.format, |
| 326 level.width, | 339 level.type, level.cleared); |
| 327 level.height, | |
| 328 level.depth, | |
| 329 level.border, | |
| 330 level.format, | |
| 331 level.type, | |
| 332 level.cleared); | |
| 333 std::vector<LevelInfo> infos; | |
| 334 infos.push_back(info); | |
| 335 level_infos_.push_back(infos); | |
| 336 } | 340 } |
| 337 | 341 |
| 338 TextureDefinition::~TextureDefinition() { | 342 TextureDefinition::~TextureDefinition() { |
| 339 } | 343 } |
| 340 | 344 |
| 341 Texture* TextureDefinition::CreateTexture() const { | 345 Texture* TextureDefinition::CreateTexture() const { |
| 342 if (!image_buffer_.get()) | |
| 343 return NULL; | |
| 344 | |
| 345 GLuint texture_id; | 346 GLuint texture_id; |
| 346 glGenTextures(1, &texture_id); | 347 glGenTextures(1, &texture_id); |
| 347 | 348 |
| 348 Texture* texture(new Texture(texture_id)); | 349 Texture* texture(new Texture(texture_id)); |
| 349 UpdateTexture(texture); | 350 UpdateTexture(texture); |
| 350 | 351 |
| 351 return texture; | 352 return texture; |
| 352 } | 353 } |
| 353 | 354 |
| 354 void TextureDefinition::UpdateTexture(Texture* texture) const { | 355 void TextureDefinition::UpdateTexture(Texture* texture) const { |
| 355 gfx::ScopedTextureBinder texture_binder(target_, texture->service_id()); | 356 gfx::ScopedTextureBinder texture_binder(target_, texture->service_id()); |
| 356 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_); | 357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_); |
| 357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_); | 358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_); |
| 358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_); | 359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_); |
| 359 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_); | 360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_); |
| 360 if (image_buffer_.get()) | 361 if (image_buffer_.get()) |
| 361 image_buffer_->BindToTexture(target_); | 362 image_buffer_->BindToTexture(target_); |
| 362 // We have to make sure the changes are visible to other clients in this share | 363 // We have to make sure the changes are visible to other clients in this share |
| 363 // group. As far as the clients are concerned, the mailbox semantics only | 364 // group. As far as the clients are concerned, the mailbox semantics only |
| 364 // demand a single flush from the client after changes are first made, | 365 // demand a single flush from the client after changes are first made, |
| 365 // and it is not visible to them when another share group boundary is crossed. | 366 // and it is not visible to them when another share group boundary is crossed. |
| 366 // We could probably track this and be a bit smarter about when to flush | 367 // We could probably track this and be a bit smarter about when to flush |
| 367 // though. | 368 // though. |
| 368 glFlush(); | 369 glFlush(); |
| 369 | 370 |
| 370 texture->face_infos_.resize(1); | 371 if (defined_) { |
| 371 for (size_t i = 0; i < level_infos_.size(); i++) { | 372 texture->face_infos_.resize(1); |
| 372 const LevelInfo& base_info = level_infos_[i][0]; | 373 texture->face_infos_[0].level_infos.resize(1); |
| 373 const size_t levels_needed = TextureManager::ComputeMipMapCount( | 374 texture->SetLevelInfo(NULL, level_info_.target, 0, |
| 374 base_info.target, base_info.width, base_info.height, base_info.depth); | 375 level_info_.internal_format, level_info_.width, |
| 375 DCHECK(level_infos_.size() <= levels_needed); | 376 level_info_.height, level_info_.depth, |
| 376 texture->face_infos_[0].level_infos.resize(levels_needed); | 377 level_info_.border, level_info_.format, |
| 377 for (size_t n = 0; n < level_infos_.size(); n++) { | 378 level_info_.type, level_info_.cleared); |
| 378 const LevelInfo& info = level_infos_[i][n]; | |
| 379 texture->SetLevelInfo(NULL, | |
| 380 info.target, | |
| 381 i, | |
| 382 info.internal_format, | |
| 383 info.width, | |
| 384 info.height, | |
| 385 info.depth, | |
| 386 info.border, | |
| 387 info.format, | |
| 388 info.type, | |
| 389 info.cleared); | |
| 390 } | |
| 391 } | 379 } |
| 380 |
| 392 if (image_buffer_.get()) { | 381 if (image_buffer_.get()) { |
| 393 texture->SetLevelImage( | 382 texture->SetLevelImage( |
| 394 NULL, | 383 NULL, |
| 395 target_, | 384 target_, |
| 396 0, | 385 0, |
| 397 new GLImageSync( | 386 new GLImageSync( |
| 398 image_buffer_, | 387 image_buffer_, |
| 399 gfx::Size(level_infos_[0][0].width, level_infos_[0][0].height))); | 388 gfx::Size(level_info_.width, level_info_.height))); |
| 400 } | 389 } |
| 401 | 390 |
| 402 texture->target_ = target_; | 391 texture->target_ = target_; |
| 403 texture->SetImmutable(immutable_); | 392 texture->SetImmutable(immutable_); |
| 404 texture->min_filter_ = min_filter_; | 393 texture->min_filter_ = min_filter_; |
| 405 texture->mag_filter_ = mag_filter_; | 394 texture->mag_filter_ = mag_filter_; |
| 406 texture->wrap_s_ = wrap_s_; | 395 texture->wrap_s_ = wrap_s_; |
| 407 texture->wrap_t_ = wrap_t_; | 396 texture->wrap_t_ = wrap_t_; |
| 408 texture->usage_ = usage_; | 397 texture->usage_ = usage_; |
| 409 } | 398 } |
| 410 | 399 |
| 411 bool TextureDefinition::Matches(const Texture* texture) const { | 400 bool TextureDefinition::Matches(const Texture* texture) const { |
| 412 DCHECK(target_ == texture->target()); | 401 DCHECK(target_ == texture->target()); |
| 413 if (texture->min_filter_ != min_filter_ || | 402 if (texture->min_filter_ != min_filter_ || |
| 414 texture->mag_filter_ != mag_filter_ || | 403 texture->mag_filter_ != mag_filter_ || |
| 415 texture->wrap_s_ != wrap_s_ || | 404 texture->wrap_s_ != wrap_s_ || |
| 416 texture->wrap_t_ != wrap_t_ || | 405 texture->wrap_t_ != wrap_t_ || |
| 417 texture->SafeToRenderFrom() != SafeToRenderFrom()) { | 406 texture->SafeToRenderFrom() != SafeToRenderFrom()) { |
| 418 return false; | 407 return false; |
| 419 } | 408 } |
| 420 | 409 |
| 410 // Texture became defined. |
| 411 if (!image_buffer_.get() && texture->IsDefined()) |
| 412 return false; |
| 413 |
| 421 // All structural changes should have orphaned the texture. | 414 // All structural changes should have orphaned the texture. |
| 422 if (image_buffer_.get() && !texture->GetLevelImage(texture->target(), 0)) | 415 if (image_buffer_.get() && !texture->GetLevelImage(texture->target(), 0)) |
| 423 return false; | 416 return false; |
| 424 | 417 |
| 425 return true; | 418 return true; |
| 426 } | 419 } |
| 427 | 420 |
| 428 bool TextureDefinition::SafeToRenderFrom() const { | 421 bool TextureDefinition::SafeToRenderFrom() const { |
| 429 for (const std::vector<LevelInfo>& face_info : level_infos_) { | 422 return level_info_.cleared; |
| 430 for (const LevelInfo& level_info : face_info) { | |
| 431 if (!level_info.cleared) { | |
| 432 return false; | |
| 433 } | |
| 434 } | |
| 435 } | |
| 436 return true; | |
| 437 } | 423 } |
| 438 | 424 |
| 439 } // namespace gles2 | 425 } // namespace gles2 |
| 440 } // namespace gpu | 426 } // namespace gpu |
| OLD | NEW |