blob: 3577a947c782a0b650e86e67bd9e3c55b10fbb4f [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.
#ifndef FLUTTER_LIB_WEB_UI_SKWASM_SURFACE_H_
#define FLUTTER_LIB_WEB_UI_SKWASM_SURFACE_H_
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <emscripten.h>
#include <emscripten/html5_webgl.h>
#include <emscripten/threading.h>
#include <webgl/webgl1.h>
#include <cassert>
#include "export.h"
#include "skwasm_support.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/encode/SkPngEncoder.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include "wrappers.h"
namespace Skwasm {
// This must be kept in sync with the `ImageByteFormat` enum in dart:ui.
enum class ImageByteFormat {
rawRgba,
rawStraightRgba,
rawUnmodified,
png,
};
class TextureSourceWrapper {
public:
TextureSourceWrapper(unsigned long threadId, SkwasmObject textureSource)
: _rasterThreadId(threadId) {
skwasm_setAssociatedObjectOnThread(_rasterThreadId, this, textureSource);
}
~TextureSourceWrapper() {
skwasm_disposeAssociatedObjectOnThread(_rasterThreadId, this);
}
SkwasmObject getTextureSource() { return skwasm_getAssociatedObject(this); }
private:
unsigned long _rasterThreadId;
};
class Surface {
public:
using CallbackHandler = void(uint32_t, void*, SkwasmObject);
// Main thread only
Surface();
unsigned long getThreadId() { return _thread; }
// Main thread only
void dispose();
uint32_t renderPicture(SkPicture* picture);
uint32_t rasterizeImage(SkImage* image, ImageByteFormat format);
void setCallbackHandler(CallbackHandler* callbackHandler);
void onRenderComplete(uint32_t callbackId, SkwasmObject imageBitmap);
// Any thread
std::unique_ptr<TextureSourceWrapper> createTextureSourceWrapper(
SkwasmObject textureSource);
// Worker thread
void renderPictureOnWorker(SkPicture* picture, uint32_t callbackId);
private:
void _runWorker();
void _init();
void _dispose();
void _resizeCanvasToFit(int width, int height);
void _recreateSurface();
void _rasterizeImage(SkImage* image,
ImageByteFormat format,
uint32_t callbackId);
void _onRasterizeComplete(SkData* data, uint32_t callbackId);
std::string _canvasID;
CallbackHandler* _callbackHandler = nullptr;
uint32_t _currentCallbackId = 0;
int _canvasWidth = 0;
int _canvasHeight = 0;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE _glContext = 0;
sk_sp<GrDirectContext> _grContext = nullptr;
sk_sp<SkSurface> _surface = nullptr;
GrGLFramebufferInfo _fbInfo;
GrGLint _sampleCount;
GrGLint _stencil;
pthread_t _thread;
static void fDispose(Surface* surface);
static void fOnRenderComplete(Surface* surface,
uint32_t callbackId,
SkwasmObject imageBitmap);
static void fRasterizeImage(Surface* surface,
SkImage* image,
ImageByteFormat format,
uint32_t callbackId);
static void fOnRasterizeComplete(Surface* surface,
SkData* imageData,
uint32_t callbackId);
};
} // namespace Skwasm
#endif // FLUTTER_LIB_WEB_UI_SKWASM_SURFACE_H_