Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc

Issue 12717013: Add reference-counting for mailbox textures. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include "base/atomicops.h" 7 #include "base/atomicops.h"
8 #include "gpu/command_buffer/common/gles2_cmd_format.h" 8 #include "gpu/command_buffer/common/gles2_cmd_format.h"
9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
10 #include "gpu/command_buffer/common/id_allocator.h" 10 #include "gpu/command_buffer/common/id_allocator.h"
(...skipping 7226 matching lines...) Expand 10 before | Expand all | Expand 10 after
7237 ASSERT_EQ(static_cast<uint32>(GL_MAILBOX_SIZE_CHROMIUM), bucket->size()); 7237 ASSERT_EQ(static_cast<uint32>(GL_MAILBOX_SIZE_CHROMIUM), bucket->size());
7238 7238
7239 static const GLbyte zero[GL_MAILBOX_SIZE_CHROMIUM] = { 7239 static const GLbyte zero[GL_MAILBOX_SIZE_CHROMIUM] = {
7240 0 7240 0
7241 }; 7241 };
7242 EXPECT_NE(0, memcmp(zero, 7242 EXPECT_NE(0, memcmp(zero,
7243 bucket->GetData(0, GL_MAILBOX_SIZE_CHROMIUM), 7243 bucket->GetData(0, GL_MAILBOX_SIZE_CHROMIUM),
7244 sizeof(zero))); 7244 sizeof(zero)));
7245 } 7245 }
7246 7246
7247 TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { 7247 class TextureMailboxTest : public GLES2DecoderTestBase {
7248 GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM]; 7248 public:
7249 group().mailbox_manager()->GenerateMailboxName( 7249 TextureMailboxTest()
7250 reinterpret_cast<MailboxName*>(mailbox)); 7250 : GLES2DecoderTestBase() {
7251 7251 }
7252 memcpy(shared_memory_address_, mailbox, sizeof(mailbox)); 7252
7253 virtual void SetUp() {
7254 GLES2DecoderTestBase::SetUp();
7255
7256 // Register some extra texture ids.
7257 RegisterTexture(kClientId1, kServiceId1);
7258 RegisterTexture(kClientId2, kServiceId2);
7259 RegisterTexture(kClientId3, kServiceId3);
7260 }
7261
7262 protected:
7263 MailboxName ProduceTexture() {
7264 MailboxName mailbox;
7265 group().mailbox_manager()->GenerateMailboxName(&mailbox);
7266 memcpy(shared_memory_address_, &mailbox, sizeof(mailbox));
7267 ProduceTextureCHROMIUM produce_cmd;
7268 produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7269 EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
7270 return mailbox;
7271 }
7272
7273 void ConsumeTexture(
7274 const MailboxName& mailbox, GLuint old_texture, GLuint new_texture) {
7275 if (old_texture != new_texture) {
7276 // TextureManager::Restore will set TexParameters.
7277 EXPECT_CALL(*gl_, TexParameteri(
7278 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
7279 .Times(1)
7280 .RetiresOnSaturation();
7281 EXPECT_CALL(*gl_, TexParameteri(
7282 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
7283 .Times(1)
7284 .RetiresOnSaturation();
7285 EXPECT_CALL(*gl_, TexParameteri(
7286 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT))
7287 .Times(1)
7288 .RetiresOnSaturation();
7289 EXPECT_CALL(*gl_, TexParameteri(
7290 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT))
7291 .Times(1)
7292 .RetiresOnSaturation();
7293 #if 0
7294 EXPECT_CALL(*gl_, TexParameteri(
7295 GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_NONE))
7296 .Times(1)
7297 .RetiresOnSaturation();
7298 #endif
7299 // Assigns and binds original service size texture ID.
7300 EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(old_texture)))
7301 .Times(1)
7302 .RetiresOnSaturation();
7303 EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, new_texture))
7304 .Times(1)
7305 .RetiresOnSaturation();
7306 }
7307
7308 memcpy(shared_memory_address_, &mailbox, sizeof(mailbox));
7309 ConsumeTextureCHROMIUM consume_cmd;
7310 consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7311 EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
7312 EXPECT_EQ(GL_NO_ERROR, GetGLError());
7313 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
7314 }
7315
7316 void VerifyLevel(Texture* texture, GLint level, GLint width, GLint height,
7317 GLenum type, GLenum format) {
7318 GLint w, h;
7319 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, level, &w, &h));
7320 EXPECT_EQ(w, width);
7321 EXPECT_EQ(h, height);
7322 GLenum t, f;
7323 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, level, &t, &f));
7324 EXPECT_EQ(static_cast<GLenum>(type), t);
7325 EXPECT_EQ(static_cast<GLenum>(format), f);
7326 }
7327
7328 static const GLuint kClientId1;
7329 static const GLuint kServiceId1;
7330 static const GLuint kClientId2;
7331 static const GLuint kServiceId2;
7332 static const GLuint kClientId3;
7333 static const GLuint kServiceId3;
7334
7335 private:
7336 void RegisterTexture(GLuint client_id, GLuint service_id) {
7337 EXPECT_CALL(*gl_, GenTextures(_, _))
7338 .WillOnce(SetArgumentPointee<1>(service_id))
7339 .RetiresOnSaturation();
7340 GenHelper<GenTexturesImmediate>(client_id);
7341 Texture* texture = group().texture_manager()->GetTexture(client_id);
7342 EXPECT_EQ(service_id, texture->service_id());
7343 }
7344 };
7345
7346 const GLuint TextureMailboxTest::kClientId1 = 4100;
7347 const GLuint TextureMailboxTest::kServiceId1 = 4101;
7348 const GLuint TextureMailboxTest::kClientId2 = 4102;
7349 const GLuint TextureMailboxTest::kServiceId2 = 4103;
7350 const GLuint TextureMailboxTest::kClientId3 = 4104;
7351 const GLuint TextureMailboxTest::kServiceId3 = 4105;
7352
7353 // Produces and consumes a texture back into the same client texture.
7354 TEST_F(TextureMailboxTest, ProduceAndConsumeToSameTexture) {
7355 GLsizei level0_width = 3;
7356 GLsizei level0_height = 1;
7357 GLenum type = GL_UNSIGNED_BYTE;
7358 GLenum format = GL_RGBA;
7359
7360 DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
7361 DoTexImage2D(GL_TEXTURE_2D, 0, format, level0_width, level0_height,
7362 0, format, type, 0, 0);
7363 Texture* texture = group().texture_manager()->GetTexture(kClientId1);
7364 EXPECT_FALSE(texture->IsImmutable());
7365
7366 MailboxName mailbox = ProduceTexture();
7367
7368 VerifyLevel(texture, 0, level0_width, level0_height, type, format);
7369
7370 // The texture is the same but has become immutable.
7371 EXPECT_EQ(kServiceId1, texture->service_id());
7372 EXPECT_TRUE(texture->IsImmutable());
7373
7374 ConsumeTexture(mailbox, kServiceId1, kServiceId1);
7375
7376 // Texture is unchanged but mutable.
7377 VerifyLevel(texture, 0, level0_width, level0_height, type, format);
7378 EXPECT_EQ(kServiceId1, texture->service_id());
7379 EXPECT_FALSE(texture->IsImmutable());
7380
7381 DoDeleteTexture(kClientId1, kServiceId1);
7382
7383 // The texture should have been removed from the mailbox.
7384 EXPECT_TRUE(group().mailbox_manager()->
7385 ConsumeTexture(GL_TEXTURE_2D, mailbox) == NULL);
7386 }
7387
7388 // Produces and consumes two textures between two clients.
7389 TEST_F(TextureMailboxTest, ProduceAndConsumeTextures) {
7390 const GLsizei level0_width = 3;
7391 const GLsizei level0_height = 1;
7392 const GLsizei level1_width = 2;
7393 const GLsizei level1_height = 4;
7394 const GLenum type = GL_UNSIGNED_BYTE;
7395 const GLenum format = GL_RGBA;
7396
7397 // Produce a texture with two levels.
7398 DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
7399 DoTexImage2D(GL_TEXTURE_2D, 0, format, level0_width, level0_height,
7400 0, format, type, 0, 0);
7401 DoTexImage2D(GL_TEXTURE_2D, 1, format, level1_width, level1_height,
7402 0, format, type, 0, 0);
7403 MailboxName mailbox1 = ProduceTexture();
7404
7405 // Produce a second 16x16 texture.
7406 DoBindTexture(GL_TEXTURE_2D, kClientId2, kServiceId2);
7407 DoTexImage2D(GL_TEXTURE_2D, 0, format, 16, 16,
7408 0, format, type, 0, 0);
7409 MailboxName mailbox2 = ProduceTexture();
7410
7411 // Consume the first texture.
7412 DoBindTexture(GL_TEXTURE_2D, kClientId3, kServiceId3);
7413 ConsumeTexture(mailbox1, kServiceId3, kServiceId1);
7414 Texture* texture = group().texture_manager()->GetTexture(kClientId3);
7415 EXPECT_FALSE(texture->IsImmutable());
7416
7417 // The textures should have been removed from the mailbox.
7418 EXPECT_TRUE(group().mailbox_manager()->
7419 ConsumeTexture(GL_TEXTURE_2D, mailbox1) == NULL);
7420
7421 // Delete the producer texture now and make sure it still gets cleaned up
7422 // correctly from the consumer.
7423 cmds::DeleteTextures cmd;
7424 cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7425 memcpy(shared_memory_address_, &kClientId1, sizeof(kClientId1));
7426 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7427
7428 // Texture is redefined.
7429 VerifyLevel(texture, 0, level0_width, level0_height, type, format);
7430 VerifyLevel(texture, 1, level1_width, level1_height, type, format);
7431
7432 // Service ID is unchanged.
7433 EXPECT_EQ(kServiceId1, texture->service_id());
7434
7435 // Consume the second texture.
7436 ConsumeTexture(mailbox2, kServiceId1, kServiceId2);
7437 VerifyLevel(texture, 0, 16, 16, type, format);
7438 VerifyLevel(texture, 1, 0, 0, 0, 0);
7439
7440 // The textures should have been removed from the mailbox.
7441 EXPECT_TRUE(group().mailbox_manager()->
7442 ConsumeTexture(GL_TEXTURE_2D, mailbox2) == NULL);
7443
7444 // Delete the producer client texture. The actual texture will not be
7445 // deleted yet.
7446 cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7447 memcpy(shared_memory_address_, &kClientId2, sizeof(kClientId2));
7448 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7449
7450 // Deleting the consumer-side client texure causes the actual texture to be
7451 // deleted.
7452 DoDeleteTexture(kClientId3, kServiceId2);
7453 }
7454
7455 // Produces and consumes a texture back and forth between two clients.
7456 TEST_F(TextureMailboxTest, PingPongTexture) {
7457 const GLsizei width = 2;
7458 const GLsizei height = 4;
7459 const GLenum type = GL_UNSIGNED_BYTE;
7460 const GLenum format = GL_RGBA;
7461
7462 // Produce a texture from client1.
7463 DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
7464 DoTexImage2D(GL_TEXTURE_2D, 0, format, width, height,
7465 0, format, type, 0, 0);
7466 MailboxName mailbox1 = ProduceTexture();
7467
7468 // Consume the texture from client2.
7469 DoBindTexture(GL_TEXTURE_2D, kClientId2, kServiceId2);
7470 ConsumeTexture(mailbox1, kServiceId2, kServiceId1);
7471
7472 // The textures should have been removed from the mailbox.
7473 EXPECT_TRUE(group().mailbox_manager()->
7474 ConsumeTexture(GL_TEXTURE_2D, mailbox1) == NULL);
7475
7476 // Produce it into a new mailbox.
7477 MailboxName mailbox2 = ProduceTexture();
7478 Texture* texture = group().texture_manager()->GetTexture(kClientId2);
7479 EXPECT_EQ(kServiceId1, texture->service_id());
7480 EXPECT_TRUE(texture->IsImmutable());
7481
7482 // Consume the texture back from client1.
7483 DoBindTexture(GL_TEXTURE_2D, kClientId1, kServiceId1);
7484 ConsumeTexture(mailbox2, kServiceId1, kServiceId1);
7485 texture = group().texture_manager()->GetTexture(kClientId1);
7486 EXPECT_FALSE(texture->IsImmutable());
7487 VerifyLevel(texture, 0, width, height, type, format);
7488
7489 // The textures should have been removed from the mailbox.
7490 EXPECT_TRUE(group().mailbox_manager()->
7491 ConsumeTexture(GL_TEXTURE_2D, mailbox2) == NULL);
7492
7493 // Delete the read-only side client texture.
7494 cmds::DeleteTextures cmd;
7495 cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7496 memcpy(shared_memory_address_, &kClientId2, sizeof(kClientId2));
7497 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7498
7499 // Delete the other texture, which causes it to be deleted.
7500 DoDeleteTexture(kClientId1, kServiceId1);
7501 }
7502
7503 // Produces a texture but deletes it before it gets consumed from the mailbox.
7504 TEST_F(TextureMailboxTest, ProduceAndDeleteTexture) {
7505 GLsizei width = 3;
7506 GLsizei height = 1;
7507 GLenum type = GL_UNSIGNED_BYTE;
7508 GLenum format = GL_RGBA;
7253 7509
7254 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 7510 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7255 DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 7511 DoTexImage2D(GL_TEXTURE_2D, 0, format, width, height,
7256 0, 0); 7512 0, format, type, 0, 0);
7257 DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 7513
7258 0, 0); 7514 MailboxName mailbox = ProduceTexture();
7259 Texture* texture = group().texture_manager()->GetTexture(client_texture_id_); 7515
7260 EXPECT_EQ(kServiceTextureId, texture->service_id()); 7516 // Deleting the consumer-side client texure causes the actual texture to be
7261 7517 // deleted.
7262 // Assigns and binds new service side texture ID. 7518 DoDeleteTexture(client_texture_id_, kServiceTextureId);
7263 EXPECT_CALL(*gl_, GenTextures(1, _)) 7519
7264 .WillOnce(SetArgumentPointee<1>(kNewServiceId)) 7520 // The texture should have been removed from the mailbox.
7265 .RetiresOnSaturation(); 7521 EXPECT_TRUE(group().mailbox_manager()->
7266 EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kNewServiceId)) 7522 ConsumeTexture(GL_TEXTURE_2D, mailbox) == NULL);
7267 .Times(1) 7523 }
7268 .RetiresOnSaturation();
7269
7270 ProduceTextureCHROMIUM produce_cmd;
7271 produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7272 EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
7273
7274 // Texture is zero-by-zero.
7275 GLsizei width;
7276 GLsizei height;
7277 GLenum type;
7278 GLenum internal_format;
7279
7280 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7281 EXPECT_EQ(0, width);
7282 EXPECT_EQ(0, height);
7283 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7284 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7285 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7286
7287 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
7288 EXPECT_EQ(0, width);
7289 EXPECT_EQ(0, height);
7290 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
7291 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7292 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7293
7294 // Service ID has changed.
7295 EXPECT_EQ(kNewServiceId, texture->service_id());
7296
7297 // Assigns and binds original service size texture ID.
7298 EXPECT_CALL(*gl_, DeleteTextures(1, _))
7299 .Times(1)
7300 .RetiresOnSaturation();
7301 EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
7302 .Times(1)
7303 .RetiresOnSaturation();
7304
7305 // TextureManager::Restore will set TexParameters.
7306 EXPECT_CALL(*gl_, TexParameteri(
7307 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
7308 .Times(1)
7309 .RetiresOnSaturation();
7310 EXPECT_CALL(*gl_, TexParameteri(
7311 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
7312 .Times(1)
7313 .RetiresOnSaturation();
7314 EXPECT_CALL(*gl_, TexParameteri(
7315 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT))
7316 .Times(1)
7317 .RetiresOnSaturation();
7318 EXPECT_CALL(*gl_, TexParameteri(
7319 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT))
7320 .Times(1)
7321 .RetiresOnSaturation();
7322 #if 0
7323 EXPECT_CALL(*gl_, TexParameteri(
7324 GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_NONE))
7325 .Times(1)
7326 .RetiresOnSaturation();
7327 #endif
7328
7329 ConsumeTextureCHROMIUM consume_cmd;
7330 consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7331 EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
7332
7333 // Texture is redefined.
7334 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7335 EXPECT_EQ(3, width);
7336 EXPECT_EQ(1, height);
7337 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7338 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7339 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7340
7341 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
7342 EXPECT_EQ(2, width);
7343 EXPECT_EQ(4, height);
7344 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
7345 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7346 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7347
7348 // Service ID is restored.
7349 EXPECT_EQ(kServiceTextureId, texture->service_id());
7350 }
7351
7352 7524
7353 TEST_F(GLES2DecoderTest, CanChangeSurface) { 7525 TEST_F(GLES2DecoderTest, CanChangeSurface) {
7354 scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock); 7526 scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
7355 EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject()). 7527 EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject()).
7356 WillOnce(Return(7)); 7528 WillOnce(Return(7));
7357 EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7)); 7529 EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
7358 7530
7359 decoder_->SetSurface(other_surface); 7531 decoder_->SetSurface(other_surface);
7360 } 7532 }
7361 7533
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
8478 // TODO(gman): TexImage2DImmediate 8650 // TODO(gman): TexImage2DImmediate
8479 8651
8480 // TODO(gman): TexSubImage2DImmediate 8652 // TODO(gman): TexSubImage2DImmediate
8481 8653
8482 // TODO(gman): UseProgram 8654 // TODO(gman): UseProgram
8483 8655
8484 // TODO(gman): SwapBuffers 8656 // TODO(gman): SwapBuffers
8485 8657
8486 } // namespace gles2 8658 } // namespace gles2
8487 } // namespace gpu 8659 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698