blob: 0e7665d0722d29807f2dee62f12f04a258f8c20d [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "export.h"
#include "skwasm_support.h"
#include "surface.h"
#include "wrappers.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/gpu/GpuTypes.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/GrExternalTextureGenerator.h"
#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <emscripten/html5_webgl.h>
using namespace SkImages;
namespace {
enum class PixelFormat {
rgba8888,
bgra8888,
rgbaFloat32,
};
SkColorType colorTypeForPixelFormat(PixelFormat format) {
switch (format) {
case PixelFormat::rgba8888:
return SkColorType::kRGBA_8888_SkColorType;
case PixelFormat::bgra8888:
return SkColorType::kBGRA_8888_SkColorType;
case PixelFormat::rgbaFloat32:
return SkColorType::kRGBA_F32_SkColorType;
}
}
SkAlphaType alphaTypeForPixelFormat(PixelFormat format) {
switch (format) {
case PixelFormat::rgba8888:
case PixelFormat::bgra8888:
return SkAlphaType::kPremul_SkAlphaType;
case PixelFormat::rgbaFloat32:
return SkAlphaType::kUnpremul_SkAlphaType;
}
}
class ExternalWebGLTexture : public GrExternalTexture {
public:
ExternalWebGLTexture(GrBackendTexture backendTexture,
GLuint textureId,
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)
: _backendTexture(backendTexture),
_textureId(textureId),
_webGLContext(context) {}
GrBackendTexture getBackendTexture() override { return _backendTexture; }
void dispose() override {
Skwasm::makeCurrent(_webGLContext);
glDeleteTextures(1, &_textureId);
}
private:
GrBackendTexture _backendTexture;
GLuint _textureId;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE _webGLContext;
};
} // namespace
class TextureSourceImageGenerator : public GrExternalTextureGenerator {
public:
TextureSourceImageGenerator(SkImageInfo ii,
SkwasmObject textureSource,
Skwasm::Surface* surface)
: GrExternalTextureGenerator(ii),
_textureSourceWrapper(
surface->createTextureSourceWrapper(textureSource)) {}
std::unique_ptr<GrExternalTexture> generateExternalTexture(
GrRecordingContext* context,
skgpu::Mipmapped mipmapped) override {
GrGLTextureInfo glInfo;
glInfo.fID = skwasm_createGlTextureFromTextureSource(
_textureSourceWrapper->getTextureSource(), fInfo.width(),
fInfo.height());
glInfo.fFormat = GL_RGBA8_OES;
glInfo.fTarget = GL_TEXTURE_2D;
auto backendTexture = GrBackendTextures::MakeGL(
fInfo.width(), fInfo.height(), mipmapped, glInfo);
return std::make_unique<ExternalWebGLTexture>(
backendTexture, glInfo.fID, emscripten_webgl_get_current_context());
}
private:
std::unique_ptr<Skwasm::TextureSourceWrapper> _textureSourceWrapper;
};
SKWASM_EXPORT SkImage* image_createFromPicture(SkPicture* picture,
int32_t width,
int32_t height) {
return DeferredFromPicture(sk_ref_sp<SkPicture>(picture), {width, height},
nullptr, nullptr, BitDepth::kU8,
SkColorSpace::MakeSRGB())
.release();
}
SKWASM_EXPORT SkImage* image_createFromPixels(SkData* data,
int width,
int height,
PixelFormat pixelFormat,
size_t rowByteCount) {
return SkImages::RasterFromData(
SkImageInfo::Make(width, height,
colorTypeForPixelFormat(pixelFormat),
alphaTypeForPixelFormat(pixelFormat),
SkColorSpace::MakeSRGB()),
sk_ref_sp(data), rowByteCount)
.release();
}
SKWASM_EXPORT SkImage* image_createFromTextureSource(SkwasmObject textureSource,
int width,
int height,
Skwasm::Surface* surface) {
return SkImages::DeferredFromTextureGenerator(
std::unique_ptr<TextureSourceImageGenerator>(
new TextureSourceImageGenerator(
SkImageInfo::Make(width, height,
SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kPremul_SkAlphaType),
textureSource, surface)))
.release();
}
SKWASM_EXPORT void image_ref(SkImage* image) {
image->ref();
}
SKWASM_EXPORT void image_dispose(SkImage* image) {
image->unref();
}
SKWASM_EXPORT int image_getWidth(SkImage* image) {
return image->width();
}
SKWASM_EXPORT int image_getHeight(SkImage* image) {
return image->height();
}