OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2010, Google Inc. All rights reserved. | 2 * Copyright (c) 2010, 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); | 70 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); |
71 m_context->activeTexture(m_oldActiveTextureUnit); | 71 m_context->activeTexture(m_oldActiveTextureUnit); |
72 } | 72 } |
73 | 73 |
74 private: | 74 private: |
75 WebGraphicsContext3D* m_context; | 75 WebGraphicsContext3D* m_context; |
76 GLenum m_oldActiveTextureUnit; | 76 GLenum m_oldActiveTextureUnit; |
77 Platform3DObject m_oldTextureUnitZeroId; | 77 Platform3DObject m_oldTextureUnitZeroId; |
78 }; | 78 }; |
79 | 79 |
80 class ScopedErrorCache { | |
81 public: | |
82 ScopedErrorCache(WebGraphicsContext3D* context) | |
83 : m_context(context) | |
84 { | |
85 GLenum error = m_context->getError(); | |
86 while (error != GL_NO_ERROR) { | |
87 m_cachedErrors.append(error); | |
88 error = m_context->getError(); | |
89 // Avoid infinite looping if glGetError is behaving badly. | |
90 ASSERT(m_cachedErrors.size() < 100); | |
91 } | |
92 } | |
93 | |
94 ~ScopedErrorCache() | |
95 { | |
96 while (m_cachedErrors.size()) { | |
97 m_context->synthesizeGLError(m_cachedErrors.first()); | |
98 m_cachedErrors.remove(0); | |
99 } | |
100 } | |
101 | |
102 // Check for a GLerror but keep it in the cache | |
103 GLenum peekError() | |
104 { | |
105 GLenum error = m_context->getError(); | |
106 if (error != GL_NO_ERROR) { | |
107 m_cachedErrors.append(error); | |
108 } | |
109 return error; | |
110 } | |
111 | |
112 private: | |
113 WebGraphicsContext3D* m_context; | |
114 Vector<GLenum> m_cachedErrors; | |
115 }; | |
116 | |
80 } // namespace | 117 } // namespace |
81 | 118 |
82 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, WebGraphicsContex t3D::Attributes requestedAttributes) | 119 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, WebGraphicsContex t3D::Attributes requestedAttributes) |
83 { | 120 { |
84 ASSERT(context); | 121 ASSERT(context); |
85 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.g et()); | 122 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.g et()); |
86 if (!extensionsUtil) { | 123 if (!extensionsUtil) { |
87 // This might be the first time we notice that the WebGraphicsContext3D is lost. | 124 // This might be the first time we notice that the WebGraphicsContext3D is lost. |
88 return nullptr; | 125 return nullptr; |
89 } | 126 } |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
613 } | 650 } |
614 } | 651 } |
615 | 652 |
616 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) | 653 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) |
617 { | 654 { |
618 // resize regular FBO | 655 // resize regular FBO |
619 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 656 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
620 | 657 |
621 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId); | 658 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId); |
622 | 659 |
623 allocateTextureMemory(&m_colorBuffer, size); | 660 if (!allocateTextureMemory(&m_colorBuffer, size)) |
661 return false; | |
624 | 662 |
625 if (m_multisampleMode == ImplicitResolve) | 663 if (m_multisampleMode == ImplicitResolve) |
626 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount); | 664 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount); |
627 else | 665 else |
628 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer.textureId, 0); | 666 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer.textureId, 0); |
629 | 667 |
630 m_context->bindTexture(GL_TEXTURE_2D, 0); | 668 m_context->bindTexture(GL_TEXTURE_2D, 0); |
631 | 669 |
632 if (m_multisampleMode != ExplicitResolve) | 670 if (m_multisampleMode != ExplicitResolve) { |
633 resizeDepthStencil(size); | 671 if (!resizeDepthStencil(size)) |
672 return false; | |
673 } | |
634 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP LETE) | 674 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP LETE) |
635 return false; | 675 return false; |
636 | 676 |
637 return true; | 677 return true; |
638 } | 678 } |
639 | 679 |
640 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) | 680 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) |
641 { | 681 { |
642 if (m_multisampleMode == ExplicitResolve) { | 682 if (m_multisampleMode == ExplicitResolve) { |
683 ScopedErrorCache errorCache(m_context.get()); | |
684 | |
643 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 685 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
644 | 686 |
645 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); | 687 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); |
646 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sam pleCount, m_internalRenderbufferFormat, size.width(), size.height()); | 688 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sam pleCount, m_internalRenderbufferFormat, size.width(), size.height()); |
647 | 689 |
648 if (m_context->getError() == GL_OUT_OF_MEMORY) | 690 if (errorCache.peekError() == GL_OUT_OF_MEMORY) |
649 return false; | 691 return false; |
650 | 692 |
651 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleColorBuffer); | 693 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleColorBuffer); |
652 resizeDepthStencil(size); | 694 if (!resizeDepthStencil(size)) |
695 return false; | |
653 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_ COMPLETE) | 696 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_ COMPLETE) |
654 return false; | 697 return false; |
655 } | 698 } |
656 | 699 |
657 return true; | 700 return true; |
658 } | 701 } |
659 | 702 |
660 void DrawingBuffer::resizeDepthStencil(const IntSize& size) | 703 bool DrawingBuffer::resizeDepthStencil(const IntSize& size) |
661 { | 704 { |
662 if (!m_requestedAttributes.depth && !m_requestedAttributes.stencil) | 705 if (!m_requestedAttributes.depth && !m_requestedAttributes.stencil) |
663 return; | 706 return true; |
707 | |
708 ScopedErrorCache errorCache(m_context.get()); | |
664 | 709 |
665 if (m_packedDepthStencilExtensionSupported) { | 710 if (m_packedDepthStencilExtensionSupported) { |
666 if (!m_depthStencilBuffer) | 711 if (!m_depthStencilBuffer) |
667 m_depthStencilBuffer = m_context->createRenderbuffer(); | 712 m_depthStencilBuffer = m_context->createRenderbuffer(); |
668 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 713 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); |
669 if (m_multisampleMode == ImplicitResolve) | 714 if (m_multisampleMode == ImplicitResolve) |
670 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_samp leCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); | 715 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_samp leCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
671 else if (m_multisampleMode == ExplicitResolve) | 716 else if (m_multisampleMode == ExplicitResolve) |
672 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m _sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); | 717 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m _sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
673 else | 718 else |
(...skipping 20 matching lines...) Expand all Loading... | |
694 if (m_multisampleMode == ImplicitResolve) | 739 if (m_multisampleMode == ImplicitResolve) |
695 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_ sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); | 740 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_ sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); |
696 else if (m_multisampleMode == ExplicitResolve) | 741 else if (m_multisampleMode == ExplicitResolve) |
697 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE R, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); | 742 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE R, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); |
698 else | 743 else |
699 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX 8, size.width(), size.height()); | 744 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX 8, size.width(), size.height()); |
700 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH MENT, GL_RENDERBUFFER, m_stencilBuffer); | 745 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH MENT, GL_RENDERBUFFER, m_stencilBuffer); |
701 } | 746 } |
702 } | 747 } |
703 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0); | 748 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0); |
749 | |
750 if (errorCache.peekError() == GL_OUT_OF_MEMORY) | |
751 return false; | |
752 | |
753 return true; | |
704 } | 754 } |
705 | 755 |
706 | 756 |
707 | 757 |
708 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) | 758 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) |
709 { | 759 { |
710 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer. | 760 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer. |
711 if (m_multisampleFBO) { | 761 if (m_multisampleFBO) { |
712 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 762 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
713 m_context->clear(GL_COLOR_BUFFER_BIT); | 763 m_context->clear(GL_COLOR_BUFFER_BIT); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
956 memcpy(rowA, scanline, rowBytes); | 1006 memcpy(rowA, scanline, rowBytes); |
957 } | 1007 } |
958 } | 1008 } |
959 | 1009 |
960 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) | 1010 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) |
961 { | 1011 { |
962 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); | 1012 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); |
963 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); | 1013 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); |
964 } | 1014 } |
965 | 1015 |
966 void DrawingBuffer::allocateTextureMemory(TextureInfo* info, const IntSize& size ) | 1016 bool DrawingBuffer::allocateTextureMemory(TextureInfo* info, const IntSize& size ) |
967 { | 1017 { |
1018 ScopedErrorCache errorCache(m_context.get()); | |
piman
2015/04/06 22:35:10
drive-by: this sounds pretty unfortunate to do (ma
| |
1019 | |
968 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) { | 1020 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) { |
969 deleteChromiumImageForTexture(info); | 1021 deleteChromiumImageForTexture(info); |
970 | 1022 |
971 info->imageId = m_context->createGpuMemoryBufferImageCHROMIUM(size.width (), size.height(), GL_RGBA, GC3D_SCANOUT_CHROMIUM); | 1023 info->imageId = m_context->createGpuMemoryBufferImageCHROMIUM(size.width (), size.height(), GL_RGBA, GC3D_SCANOUT_CHROMIUM); |
1024 | |
1025 if (errorCache.peekError() == GL_OUT_OF_MEMORY) | |
1026 return false; | |
1027 | |
972 if (info->imageId) { | 1028 if (info->imageId) { |
973 m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); | 1029 m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); |
974 return; | 1030 return true; |
975 } | 1031 } |
976 } | 1032 } |
977 | 1033 |
978 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | 1034 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
1035 | |
1036 if (errorCache.peekError() == GL_OUT_OF_MEMORY) | |
1037 return false; | |
1038 | |
1039 return true; | |
979 } | 1040 } |
980 | 1041 |
981 void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info) | 1042 void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info) |
982 { | 1043 { |
983 if (info->imageId) { | 1044 if (info->imageId) { |
984 m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); | 1045 m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); |
985 m_context->destroyImageCHROMIUM(info->imageId); | 1046 m_context->destroyImageCHROMIUM(info->imageId); |
986 info->imageId = 0; | 1047 info->imageId = 0; |
987 } | 1048 } |
988 } | 1049 } |
989 | 1050 |
990 } // namespace blink | 1051 } // namespace blink |
OLD | NEW |