OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 if (!offscreenCanvas()->hasPlaceholderCanvas()) { | 742 if (!offscreenCanvas()->hasPlaceholderCanvas()) { |
743 exceptionState.throwDOMException(InvalidStateError, | 743 exceptionState.throwDOMException(InvalidStateError, |
744 "Commit() was called on a context whose " | 744 "Commit() was called on a context whose " |
745 "OffscreenCanvas is not associated with a " | 745 "OffscreenCanvas is not associated with a " |
746 "canvas element."); | 746 "canvas element."); |
747 return exceptionState.reject(scriptState); | 747 return exceptionState.reject(scriptState); |
748 } | 748 } |
749 if (!drawingBuffer()) { | 749 if (!drawingBuffer()) { |
750 return offscreenCanvas()->commit(nullptr, false, scriptState); | 750 return offscreenCanvas()->commit(nullptr, false, scriptState); |
751 } | 751 } |
752 // TODO(crbug.com/646864): Make commit() work correctly with | 752 |
753 // { preserveDrawingBuffer : true }. | 753 RefPtr<StaticBitmapImage> image; |
754 if (creationAttributes().preserveDrawingBuffer()) { | |
755 int width = drawingBuffer()->size().width(); | |
756 int height = drawingBuffer()->size().height(); | |
757 SkImageInfo imageInfo = | |
758 SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, | |
759 creationAttributes().alpha() ? kPremul_SkAlphaType | |
760 : kOpaque_SkAlphaType); | |
761 image = StaticBitmapImage::create(makeImageSnapshotCopy(imageInfo)); | |
762 } else { | |
763 image = drawingBuffer()->transferToStaticBitmapImage(); | |
764 } | |
765 | |
754 return offscreenCanvas()->commit( | 766 return offscreenCanvas()->commit( |
755 std::move(drawingBuffer()->transferToStaticBitmapImage()), | 767 std::move(image), |
756 drawingBuffer()->contextProvider()->isSoftwareRendering(), scriptState); | 768 drawingBuffer()->contextProvider()->isSoftwareRendering(), scriptState); |
757 } | 769 } |
758 | 770 |
759 PassRefPtr<Image> WebGLRenderingContextBase::getImage( | 771 PassRefPtr<Image> WebGLRenderingContextBase::getImage( |
760 AccelerationHint hint, | 772 AccelerationHint hint, |
761 SnapshotReason reason) const { | 773 SnapshotReason reason) const { |
762 if (!drawingBuffer()) | 774 if (!drawingBuffer()) |
763 return nullptr; | 775 return nullptr; |
764 | 776 |
765 drawingBuffer()->resolveAndBindForReadAndDraw(); | 777 drawingBuffer()->resolveAndBindForReadAndDraw(); |
766 IntSize size = clampedCanvasSize(); | 778 IntSize size = clampedCanvasSize(); |
767 OpacityMode opacityMode = | 779 OpacityMode opacityMode = |
768 creationAttributes().hasAlpha() ? NonOpaque : Opaque; | 780 creationAttributes().hasAlpha() ? NonOpaque : Opaque; |
769 std::unique_ptr<AcceleratedImageBufferSurface> surface = | 781 std::unique_ptr<AcceleratedImageBufferSurface> surface = |
770 WTF::makeUnique<AcceleratedImageBufferSurface>(size, opacityMode); | 782 WTF::makeUnique<AcceleratedImageBufferSurface>(size, opacityMode); |
771 if (!surface->isValid()) | 783 if (!surface->isValid()) |
772 return nullptr; | 784 return nullptr; |
773 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(std::move(surface)); | 785 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(std::move(surface)); |
774 if (!buffer->copyRenderingResultsFromDrawingBuffer(drawingBuffer(), | 786 if (!buffer->copyRenderingResultsFromDrawingBuffer(drawingBuffer(), |
775 BackBuffer)) { | 787 BackBuffer)) { |
776 // copyRenderingResultsFromDrawingBuffer is expected to always succeed | 788 // copyRenderingResultsFromDrawingBuffer is expected to always succeed |
777 // because we've explicitly created an Accelerated surface and have already | 789 // because we've explicitly created an Accelerated surface and have already |
778 // validated it. | 790 // validated it. |
779 NOTREACHED(); | 791 NOTREACHED(); |
780 return nullptr; | 792 return nullptr; |
781 } | 793 } |
782 return buffer->newImageSnapshot(hint, reason); | 794 return buffer->newImageSnapshot(hint, reason); |
783 } | 795 } |
784 | 796 |
797 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshotCopy( | |
798 SkImageInfo& imageInfo) { | |
799 drawingBuffer()->resolveAndBindForReadAndDraw(); | |
800 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); | |
801 | |
802 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); | |
803 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( | |
804 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, | |
805 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr | |
806 : &disableLCDProps); | |
807 GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( | |
808 surface->getTextureHandle( | |
809 SkSurface::kDiscardWrite_TextureHandleAccess)) | |
810 ->fID; | |
811 | |
812 drawingBuffer()->copyToPlatformTexture( | |
813 gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0), | |
814 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); | |
815 return surface->makeImageSnapshot(); | |
816 } | |
817 | |
785 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { | 818 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { |
786 ImageData* imageData = nullptr; | 819 ImageData* imageData = nullptr; |
787 // TODO(ccameron): WebGL should produce sRGB images. | 820 // TODO(ccameron): WebGL should produce sRGB images. |
788 // https://crbug.com/672299 | 821 // https://crbug.com/672299 |
789 if (drawingBuffer()) { | 822 if (drawingBuffer()) { |
790 // For un-premultiplied data | 823 // For un-premultiplied data |
791 imageData = paintRenderingResultsToImageData(BackBuffer); | 824 imageData = paintRenderingResultsToImageData(BackBuffer); |
792 if (imageData) { | 825 if (imageData) { |
793 return imageData; | 826 return imageData; |
794 } | 827 } |
795 | 828 |
796 int width = drawingBuffer()->size().width(); | 829 int width = drawingBuffer()->size().width(); |
797 int height = drawingBuffer()->size().height(); | 830 int height = drawingBuffer()->size().height(); |
798 OpacityMode opacityMode = creationAttributes().alpha() ? NonOpaque : Opaque; | 831 SkImageInfo imageInfo = |
799 | 832 SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, |
800 drawingBuffer()->resolveAndBindForReadAndDraw(); | 833 creationAttributes().alpha() ? kPremul_SkAlphaType |
801 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); | 834 : kOpaque_SkAlphaType); |
802 SkImageInfo imageInfo = SkImageInfo::Make( | 835 sk_sp<SkImage> snapshot = makeImageSnapshotCopy(imageInfo); |
803 width, height, kRGBA_8888_SkColorType, | |
804 Opaque == opacityMode ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | |
805 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); | |
806 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( | |
807 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, | |
808 Opaque == opacityMode ? nullptr : &disableLCDProps); | |
809 GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( | |
810 surface->getTextureHandle( | |
811 SkSurface::kDiscardWrite_TextureHandleAccess)) | |
812 ->fID; | |
813 | |
814 drawingBuffer()->copyToPlatformTexture( | |
815 gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, | |
816 IntPoint(0, 0), IntRect(IntPoint(0, 0), drawingBuffer()->size()), | |
817 BackBuffer); | |
818 sk_sp<SkImage> snapshot = surface->makeImageSnapshot(); | |
819 if (snapshot) { | 836 if (snapshot) { |
820 imageData = ImageData::create(drawingBuffer()->size()); | 837 imageData = ImageData::create(drawingBuffer()->size()); |
821 snapshot->readPixels(imageInfo, imageData->data()->data(), | 838 snapshot->readPixels(imageInfo, imageData->data()->data(), |
822 imageInfo.minRowBytes(), 0, 0); | 839 imageInfo.minRowBytes(), 0, 0); |
823 } | 840 } |
824 } | 841 } |
825 return imageData; | 842 return imageData; |
826 } | 843 } |
827 | 844 |
828 namespace { | 845 namespace { |
(...skipping 3282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4111 GLsizei width, | 4128 GLsizei width, |
4112 GLsizei height, | 4129 GLsizei height, |
4113 GLenum format, | 4130 GLenum format, |
4114 GLenum type, | 4131 GLenum type, |
4115 DOMArrayBufferView* pixels, | 4132 DOMArrayBufferView* pixels, |
4116 GLuint offset) { | 4133 GLuint offset) { |
4117 if (isContextLost()) | 4134 if (isContextLost()) |
4118 return; | 4135 return; |
4119 // Due to WebGL's same-origin restrictions, it is not possible to | 4136 // Due to WebGL's same-origin restrictions, it is not possible to |
4120 // taint the origin using the WebGL API. | 4137 // taint the origin using the WebGL API. |
4121 ASSERT(canvas()->originClean()); | 4138 if (canvas()) { |
Justin Novosad
2017/01/11 21:40:04
The way this is written, canvas() will get called
Ken Russell (switch to Gerrit)
2017/01/12 02:01:45
Yes, let's not call this in release builds. You co
xlai (Olivia)
2017/01/12 20:04:47
Done.
| |
4139 DCHECK(canvas()->originClean()); | |
4140 } else { // Calling from OffscreenCanvas webgl context | |
4141 DCHECK(offscreenCanvas()->originClean()); | |
4142 } | |
4143 | |
4122 // Validate input parameters. | 4144 // Validate input parameters. |
4123 if (!pixels) { | 4145 if (!pixels) { |
4124 synthesizeGLError(GL_INVALID_VALUE, "readPixels", | 4146 synthesizeGLError(GL_INVALID_VALUE, "readPixels", |
4125 "no destination ArrayBufferView"); | 4147 "no destination ArrayBufferView"); |
4126 return; | 4148 return; |
4127 } | 4149 } |
4128 CheckedNumeric<GLuint> offsetInBytes = offset; | 4150 CheckedNumeric<GLuint> offsetInBytes = offset; |
4129 offsetInBytes *= pixels->typeSize(); | 4151 offsetInBytes *= pixels->typeSize(); |
4130 if (!offsetInBytes.IsValid() || | 4152 if (!offsetInBytes.IsValid() || |
4131 offsetInBytes.ValueOrDie() > pixels->byteLength()) { | 4153 offsetInBytes.ValueOrDie() > pixels->byteLength()) { |
(...skipping 3686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7818 | 7840 |
7819 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7841 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
7820 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7842 HTMLCanvasElementOrOffscreenCanvas& result) const { |
7821 if (canvas()) | 7843 if (canvas()) |
7822 result.setHTMLCanvasElement(canvas()); | 7844 result.setHTMLCanvasElement(canvas()); |
7823 else | 7845 else |
7824 result.setOffscreenCanvas(offscreenCanvas()); | 7846 result.setOffscreenCanvas(offscreenCanvas()); |
7825 } | 7847 } |
7826 | 7848 |
7827 } // namespace blink | 7849 } // namespace blink |
OLD | NEW |