Index: third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp |
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp |
index ea89f7b72db128a7c59a2b1d13142b45dcf12515..cd76dae4ac4b789f5f52f025f4c6a16558e1bcc2 100644 |
--- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp |
+++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasModules.cpp |
@@ -4,9 +4,15 @@ |
#include "modules/offscreencanvas/OffscreenCanvasModules.h" |
+#include "core/fileapi/Blob.h" |
+#include "core/html/ImageData.h" |
+#include "core/html/canvas/CanvasAsyncBlobCreator.h" |
#include "core/html/canvas/CanvasContextCreationAttributes.h" |
#include "core/offscreencanvas/OffscreenCanvas.h" |
#include "modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h" |
+#include "modules/webgl/WebGLRenderingContextBase.h" |
+#include "platform/graphics/StaticBitmapImage.h" |
+#include "platform/image-encoders/ImageEncoderUtils.h" |
namespace blink { |
@@ -29,4 +35,95 @@ void OffscreenCanvasModules::getContext( |
context->setOffscreenCanvasGetContextResult(result); |
} |
+ImageData* OffscreenCanvasModules::toImageData(OffscreenCanvas& offscreenCanvas, |
xlai (Olivia)
2016/10/19 18:51:06
This function requires a higher-level view of Offs
|
+ SourceDrawingBuffer sourceBuffer, |
+ SnapshotReason reason) { |
+ ImageData* imageData = nullptr; |
+ if (!offscreenCanvas.renderingContext()) |
+ return imageData; |
+ if (offscreenCanvas.renderingContext()->is3d()) { |
+ // TODO: Furnish toImageData in webgl renderingcontext for jpeg and webp |
+ // images. See crbug.com/657531. |
xlai (Olivia)
2016/10/19 18:51:06
I might be missing something here in converting we
|
+ WebGLRenderingContextBase* webglContext = |
+ toWebGLRenderingContextBase(offscreenCanvas.renderingContext()); |
+ imageData = ImageData::create(offscreenCanvas.size()); |
+ if (webglContext->drawingBuffer()) { |
+ sk_sp<SkImage> snapshot = webglContext->drawingBuffer() |
+ ->transferToStaticBitmapImage() |
+ ->imageForCurrentFrame(); |
+ if (snapshot) { |
+ SkImageInfo imageInfo = |
+ SkImageInfo::Make(offscreenCanvas.width(), offscreenCanvas.height(), |
+ kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); |
+ snapshot->readPixels(imageInfo, imageData->data()->data(), |
+ imageInfo.minRowBytes(), 0, 0); |
+ } |
+ } |
+ return imageData; |
+ } |
+ |
+ if (offscreenCanvas.renderingContext()->is2d()) { |
+ OffscreenCanvasRenderingContext2D* context2d = |
+ toOffscreenCanvasRenderingContext2D(offscreenCanvas.renderingContext()); |
+ imageData = ImageData::create(offscreenCanvas.size()); |
+ if (context2d->imageBuffer()) { |
+ sk_sp<SkImage> snapshot = context2d->imageBuffer()->newSkImageSnapshot( |
+ PreferNoAcceleration, reason); |
+ if (snapshot) { |
+ SkImageInfo imageInfo = |
+ SkImageInfo::Make(offscreenCanvas.width(), offscreenCanvas.height(), |
+ kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); |
+ snapshot->readPixels(imageInfo, imageData->data()->data(), |
+ imageInfo.minRowBytes(), 0, 0); |
+ } |
+ } |
+ return imageData; |
+ } |
+ |
+ return nullptr; |
+} |
+ |
+ScriptPromise OffscreenCanvasModules::convertToBlob( |
+ ScriptState* scriptState, |
+ OffscreenCanvas& offscreenCanvas, |
+ const ImageEncodeOptions& options, |
+ ExceptionState& exceptionState) { |
+ if (offscreenCanvas.isNeutered()) { |
+ exceptionState.throwDOMException(InvalidStateError, |
+ "OffscreenCanvas object is detached."); |
+ return exceptionState.reject(scriptState); |
+ } |
+ |
+ if (!offscreenCanvas.originClean()) { |
+ exceptionState.throwSecurityError( |
+ "Tainted OffscreenCanvas may not be exported."); |
+ return exceptionState.reject(scriptState); |
+ } |
+ |
+ if (!offscreenCanvas.isPaintable()) { |
+ return ScriptPromise(); |
+ } |
+ |
+ double startTime = WTF::monotonicallyIncreasingTime(); |
+ String encodingMimeType = ImageEncoderUtils::toEncodingMimeType( |
+ options.type(), ImageEncoderUtils::EncodeReasonConvertToBlobPromise); |
+ |
+ ImageData* imageData = |
+ toImageData(offscreenCanvas, BackBuffer, SnapshotReasonUnknown); |
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
+ |
+ Document* document = |
+ scriptState->getExecutionContext()->isDocument() |
+ ? static_cast<Document*>(scriptState->getExecutionContext()) |
+ : nullptr; |
+ |
+ CanvasAsyncBlobCreator* asyncCreator = CanvasAsyncBlobCreator::create( |
+ imageData->data(), encodingMimeType, imageData->size(), nullptr, |
+ startTime, document, resolver); |
+ |
+ asyncCreator->scheduleAsyncBlobCreation(options.quality()); |
+ |
+ return resolver->promise(); |
+} |
+ |
} // namespace blink |