| 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(makeImageSnapshot(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::makeImageSnapshot( |
| 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 = makeImageSnapshot(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 DCHECK(canvas() ? canvas()->originClean() : offscreenCanvas()->originClean()); |
| 4139 |
| 4122 // Validate input parameters. | 4140 // Validate input parameters. |
| 4123 if (!pixels) { | 4141 if (!pixels) { |
| 4124 synthesizeGLError(GL_INVALID_VALUE, "readPixels", | 4142 synthesizeGLError(GL_INVALID_VALUE, "readPixels", |
| 4125 "no destination ArrayBufferView"); | 4143 "no destination ArrayBufferView"); |
| 4126 return; | 4144 return; |
| 4127 } | 4145 } |
| 4128 CheckedNumeric<GLuint> offsetInBytes = offset; | 4146 CheckedNumeric<GLuint> offsetInBytes = offset; |
| 4129 offsetInBytes *= pixels->typeSize(); | 4147 offsetInBytes *= pixels->typeSize(); |
| 4130 if (!offsetInBytes.IsValid() || | 4148 if (!offsetInBytes.IsValid() || |
| 4131 offsetInBytes.ValueOrDie() > pixels->byteLength()) { | 4149 offsetInBytes.ValueOrDie() > pixels->byteLength()) { |
| (...skipping 3689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7821 | 7839 |
| 7822 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7840 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
| 7823 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7841 HTMLCanvasElementOrOffscreenCanvas& result) const { |
| 7824 if (canvas()) | 7842 if (canvas()) |
| 7825 result.setHTMLCanvasElement(canvas()); | 7843 result.setHTMLCanvasElement(canvas()); |
| 7826 else | 7844 else |
| 7827 result.setOffscreenCanvas(offscreenCanvas()); | 7845 result.setOffscreenCanvas(offscreenCanvas()); |
| 7828 } | 7846 } |
| 7829 | 7847 |
| 7830 } // namespace blink | 7848 } // namespace blink |
| OLD | NEW |