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