blob: 9d7f56324c422d27d19f0b5996b3856534e5ff57 [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 "flutter/skwasm/render_context.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "flutter/display_list/skia/dl_sk_dispatcher.h"
#include "flutter/skwasm/export.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.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/ganesh/gl/GrGLDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLInterface.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLMakeWebGLInterface.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLTypes.h"
SKWASM_EXPORT bool skwasm_isWimp() {
return false;
}
namespace {
class SkiaRenderContext : public Skwasm::RenderContext {
public:
SkiaRenderContext(int sample_count, int stencil)
: sample_count_(sample_count),
stencil_(stencil),
gr_context_(GrDirectContexts::MakeGL(GrGLInterfaces::MakeWebGL())),
fb_info_({0, GL_RGBA8_OES}) {
gr_context_->resetContext(kRenderTarget_GrGLBackendState |
kMisc_GrGLBackendState);
}
virtual void RenderPicture(
const sk_sp<flutter::DisplayList> display_list) override {
auto canvas = surface_->getCanvas();
canvas->drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
auto dispatcher = flutter::DlSkCanvasDispatcher(canvas);
dispatcher.save();
dispatcher.drawDisplayList(display_list, 1.0f);
dispatcher.restore();
gr_context_->flush(surface_.get());
}
virtual void RenderImage(flutter::DlImage* image,
Skwasm::ImageByteFormat format) override {
auto canvas = surface_->getCanvas();
canvas->drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
// We want the pixels from the upper left corner, but glReadPixels gives us
// the pixels from the lower left corner. So we have to flip the image when
// we are drawing it to get the pixels in the desired order.
canvas->save();
canvas->scale(1, -1);
canvas->drawImage(image->skia_image(), 0, -height_);
canvas->restore();
gr_context_->flush(surface_.get());
}
virtual void Resize(int width, int height) override {
if (width_ != width || height_ != height) {
width_ = width;
height_ = height;
auto target = GrBackendRenderTargets::MakeGL(width, height, sample_count_,
stencil_, fb_info_);
surface_ = SkSurfaces::WrapBackendRenderTarget(
gr_context_.get(), target, kBottomLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType, SkColorSpace::MakeSRGB(), nullptr);
}
}
virtual void SetResourceCacheLimit(int bytes) override {
gr_context_->setResourceCacheLimit(bytes);
}
private:
sk_sp<GrDirectContext> gr_context_ = nullptr;
sk_sp<SkSurface> surface_ = nullptr;
GrGLFramebufferInfo fb_info_;
GrGLint sample_count_;
GrGLint stencil_;
int width_ = 0;
int height_ = 0;
};
} // namespace
std::unique_ptr<Skwasm::RenderContext> Skwasm::RenderContext::Make(
int sample_count,
int stencil) {
return std::make_unique<SkiaRenderContext>(sample_count, stencil);
}