Chromium Code Reviews| 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 |