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

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: 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
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(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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698