From 7781ff69a191b3c98565924a1e93d088dc5bf461 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 17 Mar 2023 17:25:58 -0300 Subject: [PATCH] Add support to render grayscale sprites with ShaderRenderer --- src/app/render/shader_renderer.cpp | 34 ++++++++++++++++++++++++++++++ src/app/render/shader_renderer.h | 1 + 2 files changed, 35 insertions(+) diff --git a/src/app/render/shader_renderer.cpp b/src/app/render/shader_renderer.cpp index 7e6228655..1be635c4f 100644 --- a/src/app/render/shader_renderer.cpp +++ b/src/app/render/shader_renderer.cpp @@ -43,6 +43,15 @@ half4 main(vec2 fragcoord) { } )"; +const char* kGrayscaleShaderCode = R"( +uniform shader iImg; + +half4 main(vec2 fragcoord) { + half4 c = iImg.eval(fragcoord); + return half4(c.rrr * c.g, c.g); +} +)"; + inline SkBlendMode to_skia(const doc::BlendMode bm) { switch (bm) { case doc::BlendMode::NORMAL: return SkBlendMode::kSrcOver; @@ -87,6 +96,7 @@ ShaderRenderer::ShaderRenderer() m_bgEffect = makeShader(kBgShaderCode).effect; m_indexedEffect = makeShader(kIndexedShaderCode).effect; + m_grayscaleEffect = makeShader(kGrayscaleShaderCode).effect; } ShaderRenderer::~ShaderRenderer() = default; @@ -431,6 +441,30 @@ void ShaderRenderer::drawImage(SkCanvas* canvas, } case doc::ColorMode::GRAYSCALE: { + // We use kR8G8_unorm_SkColorType to access gray and alpha + auto skImg = SkImage::MakeRasterData( + SkImageInfo::Make(srcImage->width(), + srcImage->height(), + kR8G8_unorm_SkColorType, + kOpaque_SkAlphaType), + skData, + srcImage->getRowStrideSize()); + + SkRuntimeShaderBuilder builder(m_grayscaleEffect); + builder.child("iImg") = skImg->makeRawShader(SkSamplingOptions(SkFilterMode::kNearest)); + + SkPaint p; + p.setAlpha(opacity); + p.setBlendMode(to_skia(blendMode)); + p.setStyle(SkPaint::kFill_Style); + p.setShader(builder.makeShader()); + + canvas->save(); + canvas->translate( + SkIntToScalar(x), + SkIntToScalar(y)); + canvas->drawRect(SkRect::MakeXYWH(0, 0, srcImage->width(), srcImage->height()), p); + canvas->restore(); break; } diff --git a/src/app/render/shader_renderer.h b/src/app/render/shader_renderer.h index e70ae3304..dce2dbf2a 100644 --- a/src/app/render/shader_renderer.h +++ b/src/app/render/shader_renderer.h @@ -89,6 +89,7 @@ namespace app { render::Projection m_proj; sk_sp m_bgEffect; sk_sp m_indexedEffect; + sk_sp m_grayscaleEffect; const doc::Sprite* m_sprite = nullptr; const doc::LayerImage* m_bgLayer = nullptr; // TODO these members are the same as in render::Render, we should