Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 2627793003: Make OffscreenCanvas Webgl Context work with preserveDrawingBuffer flag (Closed)
Patch Set: fix based on reviewer feedback Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698