OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "cc/resource_provider.h" | 5 #include "cc/resource_provider.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 | 8 |
9 #include "base/debug/alias.h" | 9 #include "base/debug/alias.h" |
10 #include "base/hash_tables.h" | 10 #include "base/hash_tables.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 } | 40 } |
41 | 41 |
42 return storageFormat; | 42 return storageFormat; |
43 } | 43 } |
44 | 44 |
45 static bool isTextureFormatSupportedForStorage(GLenum format) | 45 static bool isTextureFormatSupportedForStorage(GLenum format) |
46 { | 46 { |
47 return (format == GL_RGBA || format == GL_BGRA_EXT); | 47 return (format == GL_RGBA || format == GL_BGRA_EXT); |
48 } | 48 } |
49 | 49 |
50 static void texImage2D(WebGraphicsContext3D* context3d, | |
51 const gfx::Size& size, | |
52 GLenum format, | |
53 bool useTextureStorageExt) | |
54 { | |
55 if (useTextureStorageExt && isTextureFormatSupportedForStorage(format)) { | |
56 GLenum storageFormat = textureToStorageFormat(format); | |
57 context3d->texStorage2DEXT( | |
58 GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height()); | |
59 } else { | |
60 context3d->texImage2D(GL_TEXTURE_2D, | |
61 0, | |
62 format, | |
63 size.width(), | |
64 size.height(), | |
65 0, | |
66 format, | |
67 GL_UNSIGNED_BYTE, | |
68 0); | |
69 } | |
70 } | |
71 | |
50 ResourceProvider::Resource::Resource() | 72 ResourceProvider::Resource::Resource() |
51 : glId(0) | 73 : glId(0) |
74 , glPixelBufferId(0) | |
75 , glUploadQueryId(0) | |
52 , pixels(0) | 76 , pixels(0) |
77 , pixelBuffer(0) | |
53 , pool(0) | 78 , pool(0) |
54 , lockForReadCount(0) | 79 , lockForReadCount(0) |
55 , lockedForWrite(false) | 80 , lockedForWrite(false) |
56 , external(false) | 81 , external(false) |
57 , exported(false) | 82 , exported(false) |
58 , markedForDeletion(false) | 83 , markedForDeletion(false) |
59 , size() | 84 , size() |
60 , format(0) | 85 , format(0) |
61 , type(static_cast<ResourceType>(0)) | 86 , type(static_cast<ResourceType>(0)) |
62 { | 87 { |
63 } | 88 } |
64 | 89 |
65 ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si ze& size, GLenum format) | 90 ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si ze& size, GLenum format) |
66 : glId(textureId) | 91 : glId(textureId) |
92 , glPixelBufferId(0) | |
93 , glUploadQueryId(0) | |
67 , pixels(0) | 94 , pixels(0) |
95 , pixelBuffer(0) | |
68 , pool(pool) | 96 , pool(pool) |
69 , lockForReadCount(0) | 97 , lockForReadCount(0) |
70 , lockedForWrite(false) | 98 , lockedForWrite(false) |
71 , external(false) | 99 , external(false) |
72 , exported(false) | 100 , exported(false) |
73 , markedForDeletion(false) | 101 , markedForDeletion(false) |
74 , size(size) | 102 , size(size) |
75 , format(format) | 103 , format(format) |
76 , type(GLTexture) | 104 , type(GLTexture) |
77 { | 105 { |
78 } | 106 } |
79 | 107 |
80 ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& size, GLenum format) | 108 ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& size, GLenum format) |
81 : glId(0) | 109 : glId(0) |
110 , glPixelBufferId(0) | |
111 , glUploadQueryId(0) | |
82 , pixels(pixels) | 112 , pixels(pixels) |
113 , pixelBuffer(0) | |
83 , pool(pool) | 114 , pool(pool) |
84 , lockForReadCount(0) | 115 , lockForReadCount(0) |
85 , lockedForWrite(false) | 116 , lockedForWrite(false) |
86 , external(false) | 117 , external(false) |
87 , exported(false) | 118 , exported(false) |
88 , markedForDeletion(false) | 119 , markedForDeletion(false) |
89 , size(size) | 120 , size(size) |
90 , format(format) | 121 , format(format) |
91 , type(Bitmap) | 122 , type(Bitmap) |
92 { | 123 { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 DCHECK(context3d); | 185 DCHECK(context3d); |
155 GLC(context3d, textureId = context3d->createTexture()); | 186 GLC(context3d, textureId = context3d->createTexture()); |
156 GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, textureId)); | 187 GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, textureId)); |
157 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR)); | 188 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR)); |
158 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR)); | 189 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR)); |
159 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL _CLAMP_TO_EDGE)); | 190 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL _CLAMP_TO_EDGE)); |
160 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL _CLAMP_TO_EDGE)); | 191 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL _CLAMP_TO_EDGE)); |
161 | 192 |
162 if (m_useTextureUsageHint && hint == TextureUsageFramebuffer) | 193 if (m_useTextureUsageHint && hint == TextureUsageFramebuffer) |
163 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE)); | 194 GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE)); |
164 if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) { | 195 |
165 GLenum storageFormat = textureToStorageFormat(format); | 196 texImage2D(context3d, size, format, m_useTextureStorageExt); |
166 GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, storageForma t, size.width(), size.height())); | |
167 } else | |
168 GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D, 0, format, size.widt h(), size.height(), 0, format, GL_UNSIGNED_BYTE, 0)); | |
169 | 197 |
170 ResourceId id = m_nextId++; | 198 ResourceId id = m_nextId++; |
171 Resource resource(textureId, pool, size, format); | 199 Resource resource(textureId, pool, size, format); |
172 m_resources[id] = resource; | 200 m_resources[id] = resource; |
173 return id; | 201 return id; |
174 } | 202 } |
175 | 203 |
176 ResourceProvider::ResourceId ResourceProvider::createBitmap(int pool, const gfx: :Size& size) | 204 ResourceProvider::ResourceId ResourceProvider::createBitmap(int pool, const gfx: :Size& size) |
177 { | 205 { |
178 DCHECK(m_threadChecker.CalledOnValidThread()); | 206 DCHECK(m_threadChecker.CalledOnValidThread()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 } | 250 } |
223 | 251 |
224 void ResourceProvider::deleteResourceInternal(ResourceMap::iterator it) | 252 void ResourceProvider::deleteResourceInternal(ResourceMap::iterator it) |
225 { | 253 { |
226 Resource* resource = &it->second; | 254 Resource* resource = &it->second; |
227 if (resource->glId && !resource->external) { | 255 if (resource->glId && !resource->external) { |
228 WebGraphicsContext3D* context3d = m_context->context3D(); | 256 WebGraphicsContext3D* context3d = m_context->context3D(); |
229 DCHECK(context3d); | 257 DCHECK(context3d); |
230 GLC(context3d, context3d->deleteTexture(resource->glId)); | 258 GLC(context3d, context3d->deleteTexture(resource->glId)); |
231 } | 259 } |
260 if (resource->glUploadQueryId) { | |
261 WebGraphicsContext3D* context3d = m_context->context3D(); | |
262 DCHECK(context3d); | |
263 GLC(context3d, context3d->deleteQueryEXT(resource->glUploadQueryId)); | |
264 } | |
265 if (resource->glPixelBufferId) { | |
266 WebGraphicsContext3D* context3d = m_context->context3D(); | |
267 DCHECK(context3d); | |
268 GLC(context3d, context3d->deleteBuffer(resource->glPixelBufferId)); | |
269 } | |
232 if (resource->pixels) | 270 if (resource->pixels) |
233 delete[] resource->pixels; | 271 delete[] resource->pixels; |
272 if (resource->pixelBuffer) | |
273 delete[] resource->pixelBuffer; | |
234 | 274 |
235 m_resources.erase(it); | 275 m_resources.erase(it); |
236 } | 276 } |
237 | 277 |
238 void ResourceProvider::deleteOwnedResources(int pool) | 278 void ResourceProvider::deleteOwnedResources(int pool) |
239 { | 279 { |
240 DCHECK(m_threadChecker.CalledOnValidThread()); | 280 DCHECK(m_threadChecker.CalledOnValidThread()); |
241 ResourceIdArray toDelete; | 281 ResourceIdArray toDelete; |
242 for (ResourceMap::iterator it = m_resources.begin(); it != m_resources.end() ; ++it) { | 282 for (ResourceMap::iterator it = m_resources.begin(); it != m_resources.end() ; ++it) { |
243 if (it->second.pool == pool && !it->second.external && !it->second.marke dForDeletion) | 283 if (it->second.pool == pool && !it->second.external && !it->second.marke dForDeletion) |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
653 GLC(context3d, context3d->genMailboxCHROMIUM(name)); | 693 GLC(context3d, context3d->genMailboxCHROMIUM(name)); |
654 source->mailbox.setName(name); | 694 source->mailbox.setName(name); |
655 } | 695 } |
656 | 696 |
657 resource->mailbox = source->mailbox; | 697 resource->mailbox = source->mailbox; |
658 GLC(context, context->bindTexture(GL_TEXTURE_2D, source->glId)); | 698 GLC(context, context->bindTexture(GL_TEXTURE_2D, source->glId)); |
659 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbo x.name)); | 699 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbo x.name)); |
660 return true; | 700 return true; |
661 } | 701 } |
662 | 702 |
703 void ResourceProvider::acquirePixelBuffer(ResourceId id) | |
704 { | |
705 DCHECK(m_threadChecker.CalledOnValidThread()); | |
706 ResourceMap::iterator it = m_resources.find(id); | |
707 CHECK(it != m_resources.end()); | |
708 Resource* resource = &it->second; | |
709 DCHECK(!resource->external); | |
710 DCHECK(!resource->exported); | |
711 | |
712 if (resource->glId) { | |
713 if (resource->glPixelBufferId) | |
714 return; | |
715 WebGraphicsContext3D* context3d = m_context->context3D(); | |
716 DCHECK(context3d); | |
717 resource->glPixelBufferId = context3d->createBuffer(); | |
718 context3d->bindBuffer( | |
719 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
720 resource->glPixelBufferId); | |
721 context3d->bufferData( | |
722 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
723 resource->size.width() * resource->size.height() * 4, | |
724 NULL, | |
725 GL_DYNAMIC_DRAW); | |
726 context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
727 } | |
728 | |
729 if (resource->pixels) { | |
730 if (resource->pixelBuffer) | |
731 return; | |
732 | |
733 resource->pixelBuffer = new uint8_t[ | |
734 resource->size.width() * resource->size.height() * 4]; | |
735 } | |
736 } | |
737 | |
738 void ResourceProvider::releasePixelBuffer(ResourceId id) | |
739 { | |
740 DCHECK(m_threadChecker.CalledOnValidThread()); | |
741 ResourceMap::iterator it = m_resources.find(id); | |
742 CHECK(it != m_resources.end()); | |
743 Resource* resource = &it->second; | |
744 DCHECK(!resource->external); | |
745 DCHECK(!resource->exported); | |
746 | |
747 if (resource->glId) { | |
748 if (!resource->glPixelBufferId) | |
749 return; | |
750 WebGraphicsContext3D* context3d = m_context->context3D(); | |
751 DCHECK(context3d); | |
752 context3d->deleteBuffer(resource->glPixelBufferId); | |
753 resource->glPixelBufferId = 0; | |
754 } | |
755 | |
756 if (resource->pixels) { | |
757 if (!resource->pixelBuffer) | |
758 return; | |
759 delete[] resource->pixelBuffer; | |
760 resource->pixelBuffer = 0; | |
761 } | |
762 } | |
763 | |
764 uint8_t* ResourceProvider::mapPixelBuffer(ResourceId id) | |
765 { | |
766 DCHECK(m_threadChecker.CalledOnValidThread()); | |
767 ResourceMap::iterator it = m_resources.find(id); | |
768 CHECK(it != m_resources.end()); | |
769 Resource* resource = &it->second; | |
770 DCHECK(!resource->external); | |
771 DCHECK(!resource->exported); | |
772 | |
773 if (resource->glId) { | |
774 WebGraphicsContext3D* context3d = m_context->context3D(); | |
775 DCHECK(context3d); | |
776 DCHECK(resource->glPixelBufferId); | |
777 context3d->bindBuffer( | |
778 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
779 resource->glPixelBufferId); | |
780 uint8_t* image = static_cast<uint8_t*>( | |
781 context3d->mapBufferCHROMIUM( | |
782 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY)); | |
783 context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
784 DCHECK(image); | |
785 return image; | |
786 } | |
787 | |
788 if (resource->pixels) | |
789 return resource->pixelBuffer; | |
790 | |
791 return NULL; | |
792 } | |
793 | |
794 void ResourceProvider::unmapPixelBuffer(ResourceId id) | |
795 { | |
796 DCHECK(m_threadChecker.CalledOnValidThread()); | |
797 ResourceMap::iterator it = m_resources.find(id); | |
798 CHECK(it != m_resources.end()); | |
799 Resource* resource = &it->second; | |
800 DCHECK(!resource->external); | |
801 DCHECK(!resource->exported); | |
802 | |
803 if (resource->glId) { | |
804 WebGraphicsContext3D* context3d = m_context->context3D(); | |
805 DCHECK(context3d); | |
806 DCHECK(resource->glPixelBufferId); | |
807 context3d->bindBuffer( | |
808 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
809 resource->glPixelBufferId); | |
810 context3d->unmapBufferCHROMIUM( | |
811 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM); | |
812 context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
813 } | |
814 } | |
815 | |
816 void ResourceProvider::beginSetPixels(ResourceId id) | |
817 { | |
818 DCHECK(m_threadChecker.CalledOnValidThread()); | |
819 ResourceMap::iterator it = m_resources.find(id); | |
820 CHECK(it != m_resources.end()); | |
821 Resource* resource = &it->second; | |
822 DCHECK(!resource->lockedForWrite); | |
823 DCHECK(!resource->lockForReadCount); | |
824 DCHECK(!resource->external); | |
825 DCHECK(!resource->exported); | |
826 | |
827 if (resource->glId) { | |
828 WebGraphicsContext3D* context3d = m_context->context3D(); | |
829 DCHECK(context3d); | |
830 DCHECK(m_textureUploader.get()); | |
831 lockForWrite(id); | |
832 DCHECK(resource->glPixelBufferId); | |
833 context3d->bindTexture(GL_TEXTURE_2D, resource->glId); | |
834 context3d->bindBuffer( | |
835 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
836 resource->glPixelBufferId); | |
837 if (!resource->glUploadQueryId) | |
838 resource->glUploadQueryId = context3d->createQueryEXT(); | |
839 context3d->beginQueryEXT( | |
840 GL_ASYNC_TEXTURES_UPLOADED_CHROMIUM, resource->glUploadQueryId); | |
841 context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, | |
842 0, /* level */ | |
843 0, /* x */ | |
844 0, /* y */ | |
845 resource->size.width(), | |
846 resource->size.height(), | |
847 resource->format, | |
848 GL_UNSIGNED_BYTE, | |
849 NULL); | |
850 context3d->endQueryEXT(GL_ASYNC_TEXTURES_UPLOADED_CHROMIUM); | |
851 } | |
852 | |
853 if (resource->pixels) { | |
854 DCHECK(resource->pixelBuffer); | |
855 DCHECK(resource->format == GL_RGBA); | |
856 SkBitmap src; | |
857 src.setConfig(SkBitmap::kARGB_8888_Config, | |
858 resource->size.width(), | |
859 resource->size.height()); | |
860 src.setPixels(resource->pixelBuffer); | |
861 | |
862 ScopedWriteLockSoftware lock(this, id); | |
863 SkCanvas* dest = lock.skCanvas(); | |
864 dest->writePixels(src, 0, 0); | |
865 } | |
866 } | |
867 | |
868 bool ResourceProvider::didSetPixelsComplete(ResourceId id) { | |
869 DCHECK(m_threadChecker.CalledOnValidThread()); | |
870 ResourceMap::iterator it = m_resources.find(id); | |
871 CHECK(it != m_resources.end()); | |
872 Resource* resource = &it->second; | |
873 | |
874 if (resource->glId) { | |
875 WebGraphicsContext3D* context3d = m_context->context3D(); | |
876 DCHECK(context3d); | |
877 DCHECK(resource->glUploadQueryId); | |
878 DCHECK(resource->lockedForWrite); | |
879 unsigned complete = 1; | |
880 context3d->getQueryObjectuivEXT( | |
881 resource->glUploadQueryId, | |
882 GL_QUERY_RESULT_AVAILABLE_EXT, | |
883 &complete); | |
884 if (!complete) | |
885 return false; | |
886 | |
887 unlockForWrite(id); | |
888 } | |
889 | |
890 return true; | |
891 } | |
892 | |
893 void ResourceProvider::abortSetPixels(ResourceId id) { | |
894 DCHECK(m_threadChecker.CalledOnValidThread()); | |
895 ResourceMap::iterator it = m_resources.find(id); | |
896 CHECK(it != m_resources.end()); | |
897 Resource* resource = &it->second; | |
898 | |
899 if (resource->glId) { | |
900 WebGraphicsContext3D* context3d = m_context->context3D(); | |
901 DCHECK(context3d); | |
902 DCHECK(resource->glUploadQueryId); | |
903 DCHECK(resource->lockedForWrite); | |
904 context3d->bindTexture(GL_TEXTURE_2D, resource->glId); | |
905 texImage2D(context3d, | |
906 resource->size, | |
nduca
2012/11/23 22:16:42
if we land this, should we file a followup bug tha
reveman
2012/11/23 22:52:28
I don't have any intentions to land this until we
| |
907 resource->format, | |
908 m_useTextureStorageExt); | |
909 | |
910 unlockForWrite(id); | |
911 } | |
912 } | |
913 | |
663 } // namespace cc | 914 } // namespace cc |
OLD | NEW |