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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 ResourceProvider::Resource::Resource() | 50 ResourceProvider::Resource::Resource() |
| 51 : glId(0) | 51 : glId(0) |
| 52 , glPixelBufferId(0) | |
| 53 , glUploadQueryId(0) | |
| 52 , pixels(0) | 54 , pixels(0) |
| 55 , pixelBuffer(0) | |
| 53 , pool(0) | 56 , pool(0) |
| 54 , lockForReadCount(0) | 57 , lockForReadCount(0) |
| 55 , lockedForWrite(false) | 58 , lockedForWrite(false) |
| 56 , external(false) | 59 , external(false) |
| 57 , exported(false) | 60 , exported(false) |
| 58 , markedForDeletion(false) | 61 , markedForDeletion(false) |
| 59 , size() | 62 , size() |
| 60 , format(0) | 63 , format(0) |
| 61 , type(static_cast<ResourceType>(0)) | 64 , type(static_cast<ResourceType>(0)) |
| 62 { | 65 { |
| 63 } | 66 } |
| 64 | 67 |
| 65 ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si ze& size, GLenum format) | 68 ResourceProvider::Resource::Resource(unsigned textureId, int pool, const gfx::Si ze& size, GLenum format) |
| 66 : glId(textureId) | 69 : glId(textureId) |
| 70 , glPixelBufferId(0) | |
| 71 , glUploadQueryId(0) | |
| 67 , pixels(0) | 72 , pixels(0) |
| 73 , pixelBuffer(0) | |
| 68 , pool(pool) | 74 , pool(pool) |
| 69 , lockForReadCount(0) | 75 , lockForReadCount(0) |
| 70 , lockedForWrite(false) | 76 , lockedForWrite(false) |
| 71 , external(false) | 77 , external(false) |
| 72 , exported(false) | 78 , exported(false) |
| 73 , markedForDeletion(false) | 79 , markedForDeletion(false) |
| 74 , size(size) | 80 , size(size) |
| 75 , format(format) | 81 , format(format) |
| 76 , type(GLTexture) | 82 , type(GLTexture) |
| 77 { | 83 { |
| 78 } | 84 } |
| 79 | 85 |
| 80 ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& size, GLenum format) | 86 ResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const gfx::Size& size, GLenum format) |
| 81 : glId(0) | 87 : glId(0) |
| 88 , glPixelBufferId(0) | |
| 89 , glUploadQueryId(0) | |
| 82 , pixels(pixels) | 90 , pixels(pixels) |
| 91 , pixelBuffer(0) | |
| 83 , pool(pool) | 92 , pool(pool) |
| 84 , lockForReadCount(0) | 93 , lockForReadCount(0) |
| 85 , lockedForWrite(false) | 94 , lockedForWrite(false) |
| 86 , external(false) | 95 , external(false) |
| 87 , exported(false) | 96 , exported(false) |
| 88 , markedForDeletion(false) | 97 , markedForDeletion(false) |
| 89 , size(size) | 98 , size(size) |
| 90 , format(format) | 99 , format(format) |
| 91 , type(Bitmap) | 100 , type(Bitmap) |
| 92 { | 101 { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 } | 231 } |
| 223 | 232 |
| 224 void ResourceProvider::deleteResourceInternal(ResourceMap::iterator it) | 233 void ResourceProvider::deleteResourceInternal(ResourceMap::iterator it) |
| 225 { | 234 { |
| 226 Resource* resource = &it->second; | 235 Resource* resource = &it->second; |
| 227 if (resource->glId && !resource->external) { | 236 if (resource->glId && !resource->external) { |
| 228 WebGraphicsContext3D* context3d = m_context->context3D(); | 237 WebGraphicsContext3D* context3d = m_context->context3D(); |
| 229 DCHECK(context3d); | 238 DCHECK(context3d); |
| 230 GLC(context3d, context3d->deleteTexture(resource->glId)); | 239 GLC(context3d, context3d->deleteTexture(resource->glId)); |
| 231 } | 240 } |
| 241 if (resource->glUploadQueryId) { | |
| 242 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 243 DCHECK(context3d); | |
| 244 GLC(context3d, context3d->deleteQueryEXT(resource->glUploadQueryId)); | |
| 245 } | |
| 246 if (resource->glPixelBufferId) { | |
| 247 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 248 DCHECK(context3d); | |
| 249 GLC(context3d, context3d->deleteBuffer(resource->glPixelBufferId)); | |
| 250 } | |
| 232 if (resource->pixels) | 251 if (resource->pixels) |
| 233 delete[] resource->pixels; | 252 delete[] resource->pixels; |
| 253 if (resource->pixelBuffer) | |
| 254 delete[] resource->pixelBuffer; | |
| 234 | 255 |
| 235 m_resources.erase(it); | 256 m_resources.erase(it); |
| 236 } | 257 } |
| 237 | 258 |
| 238 void ResourceProvider::deleteOwnedResources(int pool) | 259 void ResourceProvider::deleteOwnedResources(int pool) |
| 239 { | 260 { |
| 240 DCHECK(m_threadChecker.CalledOnValidThread()); | 261 DCHECK(m_threadChecker.CalledOnValidThread()); |
| 241 ResourceIdArray toDelete; | 262 ResourceIdArray toDelete; |
| 242 for (ResourceMap::iterator it = m_resources.begin(); it != m_resources.end() ; ++it) { | 263 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) | 264 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)); | 674 GLC(context3d, context3d->genMailboxCHROMIUM(name)); |
| 654 source->mailbox.setName(name); | 675 source->mailbox.setName(name); |
| 655 } | 676 } |
| 656 | 677 |
| 657 resource->mailbox = source->mailbox; | 678 resource->mailbox = source->mailbox; |
| 658 GLC(context, context->bindTexture(GL_TEXTURE_2D, source->glId)); | 679 GLC(context, context->bindTexture(GL_TEXTURE_2D, source->glId)); |
| 659 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbo x.name)); | 680 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbo x.name)); |
| 660 return true; | 681 return true; |
| 661 } | 682 } |
| 662 | 683 |
| 684 void ResourceProvider::acquirePixelBuffer(ResourceId id) | |
| 685 { | |
| 686 DCHECK(m_threadChecker.CalledOnValidThread()); | |
| 687 ResourceMap::iterator it = m_resources.find(id); | |
| 688 CHECK(it != m_resources.end()); | |
| 689 Resource* resource = &it->second; | |
| 690 DCHECK(!resource->external); | |
| 691 DCHECK(!resource->exported); | |
| 692 | |
| 693 if (resource->glId) { | |
| 694 if (resource->glPixelBufferId) | |
| 695 return; | |
| 696 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 697 DCHECK(context3d); | |
| 698 resource->glPixelBufferId = context3d->createBuffer(); | |
| 699 context3d->bindBuffer( | |
| 700 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
| 701 resource->glPixelBufferId); | |
| 702 context3d->bufferData( | |
| 703 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
| 704 resource->size.width() * resource->size.height() * 4, | |
| 705 NULL, | |
| 706 GL_DYNAMIC_DRAW); | |
| 707 context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
| 708 } | |
| 709 | |
| 710 if (resource->pixels) { | |
| 711 if (resource->pixelBuffer) | |
| 712 return; | |
| 713 | |
| 714 resource->pixelBuffer = new uint8_t[ | |
| 715 resource->size.width() * resource->size.height() * 4]; | |
| 716 } | |
| 717 } | |
| 718 | |
| 719 void ResourceProvider::releasePixelBuffer(ResourceId id) | |
| 720 { | |
| 721 DCHECK(m_threadChecker.CalledOnValidThread()); | |
| 722 ResourceMap::iterator it = m_resources.find(id); | |
| 723 CHECK(it != m_resources.end()); | |
| 724 Resource* resource = &it->second; | |
| 725 DCHECK(!resource->external); | |
| 726 DCHECK(!resource->exported); | |
| 727 | |
| 728 if (resource->glId) { | |
| 729 if (!resource->glPixelBufferId) | |
| 730 return; | |
| 731 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 732 DCHECK(context3d); | |
| 733 context3d->deleteBuffer(resource->glPixelBufferId); | |
| 734 resource->glPixelBufferId = 0; | |
| 735 } | |
| 736 | |
| 737 if (resource->pixels) { | |
| 738 if (!resource->pixelBuffer) | |
| 739 return; | |
| 740 delete[] resource->pixelBuffer; | |
| 741 resource->pixelBuffer = 0; | |
| 742 } | |
| 743 } | |
| 744 | |
| 745 uint8_t* ResourceProvider::mapPixelBuffer(ResourceId id) | |
| 746 { | |
| 747 DCHECK(m_threadChecker.CalledOnValidThread()); | |
| 748 ResourceMap::iterator it = m_resources.find(id); | |
| 749 CHECK(it != m_resources.end()); | |
| 750 Resource* resource = &it->second; | |
| 751 DCHECK(!resource->external); | |
| 752 DCHECK(!resource->exported); | |
| 753 | |
| 754 if (resource->glId) { | |
| 755 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 756 DCHECK(context3d); | |
| 757 DCHECK(resource->glPixelBufferId); | |
| 758 context3d->bindBuffer( | |
| 759 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
| 760 resource->glPixelBufferId); | |
| 761 uint8_t* image = static_cast<uint8_t*>( | |
| 762 context3d->mapBufferCHROMIUM( | |
| 763 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY)); | |
| 764 context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
| 765 DCHECK(image); | |
| 766 return image; | |
| 767 } | |
| 768 | |
| 769 if (resource->pixels) | |
| 770 return resource->pixelBuffer; | |
| 771 | |
| 772 return NULL; | |
| 773 } | |
| 774 | |
| 775 void ResourceProvider::unmapPixelBuffer(ResourceId id) | |
| 776 { | |
| 777 DCHECK(m_threadChecker.CalledOnValidThread()); | |
| 778 ResourceMap::iterator it = m_resources.find(id); | |
| 779 CHECK(it != m_resources.end()); | |
| 780 Resource* resource = &it->second; | |
| 781 DCHECK(!resource->external); | |
| 782 DCHECK(!resource->exported); | |
| 783 | |
| 784 if (resource->glId) { | |
| 785 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 786 DCHECK(context3d); | |
| 787 DCHECK(resource->glPixelBufferId); | |
| 788 context3d->bindBuffer( | |
| 789 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
| 790 resource->glPixelBufferId); | |
| 791 context3d->unmapBufferCHROMIUM( | |
| 792 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM); | |
| 793 context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
| 794 } | |
| 795 } | |
| 796 | |
| 797 void ResourceProvider::scheduleSetPixels(ResourceId id) | |
| 798 { | |
| 799 DCHECK(m_threadChecker.CalledOnValidThread()); | |
| 800 ResourceMap::iterator it = m_resources.find(id); | |
| 801 CHECK(it != m_resources.end()); | |
| 802 Resource* resource = &it->second; | |
| 803 DCHECK(!resource->lockedForWrite); | |
| 804 DCHECK(!resource->lockForReadCount); | |
| 805 DCHECK(!resource->external); | |
| 806 DCHECK(!resource->exported); | |
| 807 | |
| 808 if (resource->glId) { | |
| 809 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 810 DCHECK(context3d); | |
| 811 DCHECK(m_textureUploader.get()); | |
| 812 DCHECK(resource->glPixelBufferId); | |
| 813 context3d->bindTexture(GL_TEXTURE_2D, resource->glId); | |
|
danakj
2012/11/17 17:47:25
Should this be locking for write?
reveman
2012/11/18 18:15:59
Maybe but we currently don't lock for write in set
danakj
2012/11/18 18:22:49
Well my thought is that setPixels doesn't set the
reveman
2012/11/18 19:04:42
Ok, that makes sense. I added the write lock but w
| |
| 814 context3d->bindBuffer( | |
| 815 GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, | |
| 816 resource->glPixelBufferId); | |
| 817 if (!resource->glUploadQueryId) | |
| 818 resource->glUploadQueryId = context3d->createQueryEXT(); | |
| 819 context3d->beginQueryEXT( | |
| 820 GL_ASYNC_TEXTURES_UPLOADED_CHROMIUM, resource->glUploadQueryId); | |
| 821 context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, | |
| 822 0, /* level */ | |
| 823 0, /* x */ | |
| 824 0, /* y */ | |
| 825 resource->size.width(), | |
| 826 resource->size.height(), | |
| 827 resource->format, | |
| 828 GL_UNSIGNED_BYTE, | |
| 829 NULL); | |
| 830 context3d->endQueryEXT(GL_ASYNC_TEXTURES_UPLOADED_CHROMIUM); | |
| 831 } | |
| 832 | |
| 833 if (resource->pixels) { | |
| 834 DCHECK(resource->pixelBuffer); | |
| 835 DCHECK(resource->format == GL_RGBA); | |
| 836 SkBitmap src; | |
| 837 src.setConfig(SkBitmap::kARGB_8888_Config, | |
| 838 resource->size.width(), | |
| 839 resource->size.height()); | |
| 840 src.setPixels(resource->pixelBuffer); | |
| 841 | |
| 842 ScopedWriteLockSoftware lock(this, id); | |
| 843 SkCanvas* dest = lock.skCanvas(); | |
| 844 dest->writePixels(src, 0, 0); | |
| 845 } | |
| 846 } | |
| 847 | |
| 848 bool ResourceProvider::didSetPixelsComplete(ResourceId id) { | |
| 849 DCHECK(m_threadChecker.CalledOnValidThread()); | |
| 850 ResourceMap::iterator it = m_resources.find(id); | |
| 851 CHECK(it != m_resources.end()); | |
| 852 Resource* resource = &it->second; | |
| 853 DCHECK(!resource->lockedForWrite); | |
| 854 DCHECK(!resource->lockForReadCount); | |
| 855 DCHECK(!resource->external); | |
| 856 DCHECK(!resource->exported); | |
| 857 | |
| 858 if (resource->glId) { | |
|
nduca
2012/11/17 17:10:30
behavior on context lost?
danakj
2012/11/17 17:47:25
+1, also consider the lock, if we write lock durin
reveman
2012/11/18 18:15:59
This returns true on context lost (same behavior a
| |
| 859 WebGraphicsContext3D* context3d = m_context->context3D(); | |
| 860 DCHECK(context3d); | |
| 861 DCHECK(m_textureUploader.get()); | |
| 862 DCHECK(resource->glUploadQueryId); | |
| 863 unsigned complete = 1; | |
| 864 context3d->getQueryObjectuivEXT( | |
| 865 resource->glUploadQueryId, | |
| 866 GL_QUERY_RESULT_AVAILABLE_EXT, | |
| 867 &complete); | |
| 868 return complete; | |
| 869 } | |
| 870 | |
| 871 return true; | |
| 872 } | |
| 873 | |
| 663 } // namespace cc | 874 } // namespace cc |
| OLD | NEW |