| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #include "wtf/RefPtr.h" | 45 #include "wtf/RefPtr.h" |
| 46 | 46 |
| 47 using testing::Test; | 47 using testing::Test; |
| 48 using testing::_; | 48 using testing::_; |
| 49 | 49 |
| 50 namespace blink { | 50 namespace blink { |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 | 53 |
| 54 // The target to use when binding a texture to a Chromium image. | 54 // The target to use when binding a texture to a Chromium image. |
| 55 GLenum imageTextureTarget() | 55 GLenum imageCHROMIUMTextureTarget() |
| 56 { | 56 { |
| 57 #if OS(MACOSX) | 57 #if OS(MACOSX) |
| 58 return GC3D_TEXTURE_RECTANGLE_ARB; | 58 return GC3D_TEXTURE_RECTANGLE_ARB; |
| 59 #else | 59 #else |
| 60 return GL_TEXTURE_2D; | 60 return GL_TEXTURE_2D; |
| 61 #endif | 61 #endif |
| 62 } | 62 } |
| 63 | 63 |
| 64 // The target to use when preparing a mailbox texture. | 64 // The target to use when preparing a mailbox texture. |
| 65 GLenum drawingBufferTextureTarget(bool allowImageChromium) | 65 GLenum drawingBufferTextureTarget() |
| 66 { | 66 { |
| 67 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled() && allowImageChromiu
m) | 67 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) |
| 68 return imageTextureTarget(); | 68 return imageCHROMIUMTextureTarget(); |
| 69 return GL_TEXTURE_2D; | 69 return GL_TEXTURE_2D; |
| 70 } | 70 } |
| 71 | 71 |
| 72 } // namespace | 72 } // namespace |
| 73 | 73 |
| 74 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 74 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { |
| 75 public: | 75 public: |
| 76 void BindTexture(GLenum target, GLuint texture) override | 76 void BindTexture(GLenum target, GLuint texture) override |
| 77 { | 77 { |
| 78 if (target != m_boundTextureTarget && texture == 0) | 78 if (target != m_boundTextureTarget && texture == 0) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 | 116 |
| 117 void GenMailboxCHROMIUM(GLbyte* mailbox) override | 117 void GenMailboxCHROMIUM(GLbyte* mailbox) override |
| 118 { | 118 { |
| 119 ++m_currentMailboxByte; | 119 ++m_currentMailboxByte; |
| 120 WebExternalTextureMailbox temp; | 120 WebExternalTextureMailbox temp; |
| 121 memset(mailbox, m_currentMailboxByte, sizeof(temp.name)); | 121 memset(mailbox, m_currentMailboxByte, sizeof(temp.name)); |
| 122 } | 122 } |
| 123 | 123 |
| 124 void ProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, const GLbyt
e* mailbox) override | 124 void ProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, const GLbyt
e* mailbox) override |
| 125 { | 125 { |
| 126 ASSERT_EQ(target, drawingBufferTextureTarget(m_allowImageChromium)); | 126 ASSERT_EQ(target, drawingBufferTextureTarget()); |
| 127 ASSERT_TRUE(m_textureSizes.contains(texture)); | 127 |
| 128 m_mostRecentlyProducedSize = m_textureSizes.get(texture); | 128 if (!m_createImageChromiumFail) { |
| 129 ASSERT_TRUE(m_textureSizes.contains(texture)); |
| 130 m_mostRecentlyProducedSize = m_textureSizes.get(texture); |
| 131 } |
| 129 } | 132 } |
| 130 | 133 |
| 131 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei wi
dth, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixel
s) override | 134 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei wi
dth, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixel
s) override |
| 132 { | 135 { |
| 133 if (target == GL_TEXTURE_2D && !level) { | 136 if (target == GL_TEXTURE_2D && !level) { |
| 134 m_textureSizes.set(m_boundTexture, IntSize(width, height)); | 137 m_textureSizes.set(m_boundTexture, IntSize(width, height)); |
| 135 } | 138 } |
| 136 } | 139 } |
| 137 | 140 |
| 138 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, GLsizei height, GLe
num internalformat, GLenum usage) override | 141 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, GLsizei height, GLe
num internalformat, GLenum usage) override |
| 139 { | 142 { |
| 140 if (!m_allowImageChromium) | 143 if (m_createImageChromiumFail) |
| 141 return false; | 144 return 0; |
| 142 m_imageSizes.set(m_currentImageId, IntSize(width, height)); | 145 m_imageSizes.set(m_currentImageId, IntSize(width, height)); |
| 143 return m_currentImageId++; | 146 return m_currentImageId++; |
| 144 } | 147 } |
| 145 | 148 |
| 146 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); | 149 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); |
| 147 void DestroyImageCHROMIUM(GLuint imageId) | 150 void DestroyImageCHROMIUM(GLuint imageId) |
| 148 { | 151 { |
| 149 m_imageSizes.remove(imageId); | 152 m_imageSizes.remove(imageId); |
| 150 // No textures should be bound to this. | 153 // No textures should be bound to this. |
| 151 ASSERT(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); | 154 ASSERT(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); |
| 152 m_imageSizes.remove(imageId); | 155 m_imageSizes.remove(imageId); |
| 153 DestroyImageMock(imageId); | 156 DestroyImageMock(imageId); |
| 154 } | 157 } |
| 155 | 158 |
| 156 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); | 159 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); |
| 157 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) | 160 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) |
| 158 { | 161 { |
| 159 if (target == imageTextureTarget()) { | 162 if (target == imageCHROMIUMTextureTarget()) { |
| 160 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value
); | 163 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value
); |
| 161 m_imageToTextureMap.set(imageId, m_boundTexture); | 164 m_imageToTextureMap.set(imageId, m_boundTexture); |
| 162 BindTexImage2DMock(imageId); | 165 BindTexImage2DMock(imageId); |
| 163 } | 166 } |
| 164 } | 167 } |
| 165 | 168 |
| 166 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); | 169 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); |
| 167 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) | 170 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) |
| 168 { | 171 { |
| 169 if (target == imageTextureTarget()) { | 172 if (target == imageCHROMIUMTextureTarget()) { |
| 170 m_imageSizes.set(m_currentImageId, IntSize()); | 173 m_imageSizes.set(m_currentImageId, IntSize()); |
| 171 m_imageToTextureMap.remove(imageId); | 174 m_imageToTextureMap.remove(imageId); |
| 172 ReleaseTexImage2DMock(imageId); | 175 ReleaseTexImage2DMock(imageId); |
| 173 } | 176 } |
| 174 } | 177 } |
| 175 | 178 |
| 176 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override | 179 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override |
| 177 { | 180 { |
| 178 memcpy(syncToken, &fenceSync, sizeof(fenceSync)); | 181 memcpy(syncToken, &fenceSync, sizeof(fenceSync)); |
| 179 } | 182 } |
| 180 | 183 |
| 181 void GenTextures(GLsizei n, GLuint* textures) override | 184 void GenTextures(GLsizei n, GLuint* textures) override |
| 182 { | 185 { |
| 183 static GLuint id = 1; | 186 static GLuint id = 1; |
| 184 for (GLsizei i = 0; i < n; ++i) | 187 for (GLsizei i = 0; i < n; ++i) |
| 185 textures[i] = id++; | 188 textures[i] = id++; |
| 186 } | 189 } |
| 187 | 190 |
| 188 GLuint boundTexture() const { return m_boundTexture; } | 191 GLuint boundTexture() const { return m_boundTexture; } |
| 189 GLuint boundTextureTarget() const { return m_boundTextureTarget; } | 192 GLuint boundTextureTarget() const { return m_boundTextureTarget; } |
| 190 GLuint mostRecentlyWaitedSyncToken() const { return m_mostRecentlyWaitedSync
Token; } | 193 GLuint mostRecentlyWaitedSyncToken() const { return m_mostRecentlyWaitedSync
Token; } |
| 191 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } | 194 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } |
| 192 IntSize mostRecentlyProducedSize() const { return m_mostRecentlyProducedSize
; } | 195 IntSize mostRecentlyProducedSize() const { return m_mostRecentlyProducedSize
; } |
| 193 bool allowImageChromium() const { return m_allowImageChromium; } | |
| 194 | 196 |
| 195 void setAllowImageChromium(bool allow) { m_allowImageChromium = allow; } | 197 void setCreateImageChromiumFail(bool fail) { m_createImageChromiumFail = fai
l; } |
| 196 | 198 |
| 197 private: | 199 private: |
| 198 GLuint m_boundTexture = 0; | 200 GLuint m_boundTexture = 0; |
| 199 GLuint m_boundTextureTarget = 0; | 201 GLuint m_boundTextureTarget = 0; |
| 200 GLuint m_mostRecentlyWaitedSyncToken = 0; | 202 GLuint m_mostRecentlyWaitedSyncToken = 0; |
| 201 GLbyte m_currentMailboxByte = 0; | 203 GLbyte m_currentMailboxByte = 0; |
| 202 IntSize m_mostRecentlyProducedSize; | 204 IntSize m_mostRecentlyProducedSize; |
| 203 bool m_allowImageChromium = true; | 205 bool m_createImageChromiumFail = false; |
| 204 GLuint m_currentImageId = 1; | 206 GLuint m_currentImageId = 1; |
| 205 HashMap<GLuint, IntSize> m_textureSizes; | 207 HashMap<GLuint, IntSize> m_textureSizes; |
| 206 HashMap<GLuint, IntSize> m_imageSizes; | 208 HashMap<GLuint, IntSize> m_imageSizes; |
| 207 HashMap<GLuint, GLuint> m_imageToTextureMap; | 209 HashMap<GLuint, GLuint> m_imageToTextureMap; |
| 208 }; | 210 }; |
| 209 | 211 |
| 210 static const int initialWidth = 100; | 212 static const int initialWidth = 100; |
| 211 static const int initialHeight = 100; | 213 static const int initialHeight = 100; |
| 212 static const int alternateHeight = 50; | 214 static const int alternateHeight = 50; |
| 213 | 215 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 m_drawingBuffer->mailboxReleased(mailbox, false); | 574 m_drawingBuffer->mailboxReleased(mailbox, false); |
| 573 | 575 |
| 574 EXPECT_CALL(*m_gl, DestroyImageMock(m_imageId5)).Times(1); | 576 EXPECT_CALL(*m_gl, DestroyImageMock(m_imageId5)).Times(1); |
| 575 EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(m_imageId5)).Times(1); | 577 EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(m_imageId5)).Times(1); |
| 576 EXPECT_CALL(*m_gl, DestroyImageMock(m_imageId4)).Times(1); | 578 EXPECT_CALL(*m_gl, DestroyImageMock(m_imageId4)).Times(1); |
| 577 EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(m_imageId4)).Times(1); | 579 EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(m_imageId4)).Times(1); |
| 578 m_drawingBuffer->beginDestruction(); | 580 m_drawingBuffer->beginDestruction(); |
| 579 testing::Mock::VerifyAndClearExpectations(m_gl); | 581 testing::Mock::VerifyAndClearExpectations(m_gl); |
| 580 } | 582 } |
| 581 | 583 |
| 584 TEST_F(DrawingBufferImageChromiumTest, allocationFailure) |
| 585 { |
| 586 WebExternalTextureMailbox mailboxes[3]; |
| 587 |
| 588 // Request a mailbox. An image should already be created. Everything works |
| 589 // as expected. |
| 590 EXPECT_CALL(*m_gl, BindTexImage2DMock(_)).Times(1); |
| 591 IntSize initialSize(initialWidth, initialHeight); |
| 592 m_drawingBuffer->markContentsChanged(); |
| 593 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailboxes[0], 0)); |
| 594 EXPECT_TRUE(mailboxes[0].allowOverlay); |
| 595 testing::Mock::VerifyAndClearExpectations(m_gl); |
| 596 |
| 597 // Force image CHROMIUM creation failure. Request another mailbox. It should |
| 598 // still be provided, but this time with allowOverlay = false. |
| 599 m_gl->setCreateImageChromiumFail(true); |
| 600 m_drawingBuffer->markContentsChanged(); |
| 601 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailboxes[1], 0)); |
| 602 EXPECT_FALSE(mailboxes[1].allowOverlay); |
| 603 |
| 604 // Check that if image CHROMIUM starts working again, mailboxes are |
| 605 // correctly created with allowOverlay = true. |
| 606 EXPECT_CALL(*m_gl, BindTexImage2DMock(_)).Times(1); |
| 607 m_gl->setCreateImageChromiumFail(false); |
| 608 m_drawingBuffer->markContentsChanged(); |
| 609 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailboxes[2], 0)); |
| 610 EXPECT_TRUE(mailboxes[2].allowOverlay); |
| 611 testing::Mock::VerifyAndClearExpectations(m_gl); |
| 612 |
| 613 for (int i = 0; i < 3; ++i) |
| 614 m_drawingBuffer->mailboxReleased(mailboxes[i], false); |
| 615 |
| 616 EXPECT_CALL(*m_gl, DestroyImageMock(_)).Times(3); |
| 617 EXPECT_CALL(*m_gl, ReleaseTexImage2DMock(_)).Times(3); |
| 618 m_drawingBuffer->beginDestruction(); |
| 619 testing::Mock::VerifyAndClearExpectations(m_gl); |
| 620 } |
| 621 |
| 582 class DepthStencilTrackingGLES2Interface : public gpu::gles2::GLES2InterfaceStub
{ | 622 class DepthStencilTrackingGLES2Interface : public gpu::gles2::GLES2InterfaceStub
{ |
| 583 public: | 623 public: |
| 584 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum render
buffertarget, GLuint renderbuffer) override | 624 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum render
buffertarget, GLuint renderbuffer) override |
| 585 { | 625 { |
| 586 switch (attachment) { | 626 switch (attachment) { |
| 587 case GL_DEPTH_ATTACHMENT: | 627 case GL_DEPTH_ATTACHMENT: |
| 588 m_depthAttachment = renderbuffer; | 628 m_depthAttachment = renderbuffer; |
| 589 break; | 629 break; |
| 590 case GL_STENCIL_ATTACHMENT: | 630 case GL_STENCIL_ATTACHMENT: |
| 591 m_stencilAttachment = renderbuffer; | 631 m_stencilAttachment = renderbuffer; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 m_drawingBuffer->mailboxReleased(mailbox); | 773 m_drawingBuffer->mailboxReleased(mailbox); |
| 734 // m_drawingBuffer deletes mailbox immediately when hidden. | 774 // m_drawingBuffer deletes mailbox immediately when hidden. |
| 735 | 775 |
| 736 GLuint waitSyncToken = 0; | 776 GLuint waitSyncToken = 0; |
| 737 memcpy(&waitSyncToken, mailbox.syncToken, sizeof(waitSyncToken)); | 777 memcpy(&waitSyncToken, mailbox.syncToken, sizeof(waitSyncToken)); |
| 738 EXPECT_EQ(waitSyncToken, m_gl->mostRecentlyWaitedSyncToken()); | 778 EXPECT_EQ(waitSyncToken, m_gl->mostRecentlyWaitedSyncToken()); |
| 739 | 779 |
| 740 m_drawingBuffer->beginDestruction(); | 780 m_drawingBuffer->beginDestruction(); |
| 741 } | 781 } |
| 742 | 782 |
| 743 class DrawingBufferImageChromiumFallbackTest : public DrawingBufferTest { | |
| 744 protected: | |
| 745 void SetUp() override | |
| 746 { | |
| 747 OwnPtr<GLES2InterfaceForTests> gl = adoptPtr(new GLES2InterfaceForTests)
; | |
| 748 gl->setAllowImageChromium(false); | |
| 749 m_gl = gl.get(); | |
| 750 OwnPtr<WebGraphicsContext3DProviderForTests> provider = adoptPtr(new Web
GraphicsContext3DProviderForTests(std::move(gl))); | |
| 751 RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(true); | |
| 752 m_drawingBuffer = DrawingBufferForTests::create(std::move(provider), | |
| 753 IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve); | |
| 754 } | |
| 755 | |
| 756 void TearDown() override | |
| 757 { | |
| 758 RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(false); | |
| 759 } | |
| 760 }; | |
| 761 | |
| 762 TEST_F(DrawingBufferImageChromiumFallbackTest, verifyImageChromiumFallback) | |
| 763 { | |
| 764 WebExternalTextureMailbox mailbox; | |
| 765 | |
| 766 IntSize initialSize(initialWidth, initialHeight); | |
| 767 m_drawingBuffer->markContentsChanged(); | |
| 768 EXPECT_TRUE(m_drawingBuffer->prepareMailbox(&mailbox, 0)); | |
| 769 EXPECT_EQ(initialSize, m_gl->mostRecentlyProducedSize()); | |
| 770 EXPECT_FALSE(mailbox.allowOverlay); | |
| 771 | |
| 772 m_drawingBuffer->mailboxReleased(mailbox, false); | |
| 773 m_drawingBuffer->beginDestruction(); | |
| 774 } | |
| 775 | |
| 776 } // namespace blink | 783 } // namespace blink |
| OLD | NEW |