Chromium Code Reviews| 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 |