SKIA FIDDLE - TEXT GEOMERTY INCONSISTENT

94 views
Skip to first unread message

Clark Kent

unread,
Sep 2, 2022, 4:03:04 AM9/2/22
to skia-discuss

CPU image is with drawString x, y

GPU image is with translate x y | drawString 0, 0

```cpp

bool GPU = false;

void drawText(SkCanvas * canvas, int n, int x, int y)
{
  auto paint = SkPaint();
  paint.setColor(SK_ColorWHITE);

  for (int i = 0; i < n; i++)
  {
    std::string text = "drawn ";
    text += std::to_string(n);
    text += " time";
    if (i != 0) text += "s";
    if (!GPU)
    {
        canvas->drawString(text.c_str(), x, y, SkFont(nullptr, 12), paint);
    }
    else
    {
      canvas->save();
      canvas->translate(x, y);
      canvas->drawString(text.c_str(), 0, 0, SkFont(nullptr, 12), paint);
      canvas->restore();
    }
  }
}

void drawMatrix(SkCanvas * canvas, int count, int max_lines, int spacing)
{
  max_lines++;
  int n = 0;
  int column = 0;
  int line = 1;
  for (int i = 0; i < count; i++)
  {
    n = i + 1;
    if (line == max_lines)
    {
      line = 1;
      column += spacing;
    }
    drawText(canvas, n, column, 20 * line);
    line++;
  }
}


void draw(SkCanvas* canvas) {
  auto txtpaint = SkPaint();
  txtpaint.setColor(SK_ColorWHITE);
 
  canvas->drawColor(SK_ColorBLACK);
 
  auto sksl = SkRuntimeEffect::MakeForShader(
    SkString(
    "uniform shader input_;\n"
    "uniform shader inputAlpha;\n"
    "\n"
    "half4 main(float2 cord) {\n"
    "    half4 color = input_.eval(cord);\n"
    // return zero if alpha is zero
    "    if (color.a == 0) return vec4(0,0,0,1);\n"
    "    int alpha = (int)(255.0 * inputAlpha.eval(cord).a);\n"
    // return color if input alpha is 0, this means we only drawn this pixel once
    // Skia's overdraw canvas increases the alpha of a pixel each time it drawn touched
    // R G B A
    "    if (alpha == 0) {\n"
    // apply greyscale to the overdraw canvas in order to isolate the overdraw colors
    "       return half4(vec3((color.r + color.g + color.b) / 3), 1);\n"
    "    }\n"
    "    return half4(1,0,0,1);\n"
    "}\n")
  );
  if (sksl.effect == nullptr) {
    auto text = sksl.errorText;
    auto text_c = text.c_str();
    SkDebugf("SHADER ERROR!\n");
    SkDebugf("%s\n", text_c);
    canvas->drawString("SHADER ERROR!", 20, 40, SkFont(nullptr, 12), txtpaint);
    canvas->drawString(text_c, 0, 52, SkFont(nullptr, 12), txtpaint);
    return;
  }

  auto surface = canvas->getSurface();
  GrRecordingContext * context = surface ? surface->recordingContext() : nullptr;
  GPU = surface && context;
 
  int w = canvas->imageInfo().width();
  int h = canvas->imageInfo().height();
 
  auto offscreenInfo = canvas->imageInfo().makeWH(w, h);
  auto offscreenAlphaInfo = SkImageInfo::MakeA8(w, h);
 
  auto offscreenSurface =
    GPU ? SkSurface::MakeRenderTarget(canvas->getSurface()->recordingContext(), SkBudgeted::kNo, offscreenInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr)
      : SkSurface::MakeRaster(offscreenInfo, kTopLeft_GrSurfaceOrigin, nullptr);
  auto offscreenAlphaSurface =
    GPU ? SkSurface::MakeRenderTarget(canvas->getSurface()->recordingContext(), SkBudgeted::kNo, offscreenAlphaInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr)
      : SkSurface::MakeRaster(offscreenAlphaInfo, kTopLeft_GrSurfaceOrigin, nullptr);
 
  if (!offscreenSurface || !offscreenAlphaSurface) {
    SkDebugf("SURFACE ERROR!\n");
    canvas->drawString("SURFACE ERROR!", 20, 40, SkFont(nullptr, 12), txtpaint);
    return;
  }
 
  auto imageCanvas = offscreenSurface->getCanvas();
  auto alphaCnvas = offscreenAlphaSurface->getCanvas();
 
  if (!imageCanvas || !alphaCnvas) {
    SkDebugf("CANVAS ERROR!\n");
    canvas->drawString("CANVAS ERROR!", 20, 40, SkFont(nullptr, 12), txtpaint);
    return;
  }
 
  auto overdrawCanvas = SkOverdrawCanvas(alphaCnvas);
  auto nWayCanvas = SkNWayCanvas(w, h);

  nWayCanvas.addCanvas(&overdrawCanvas);
  nWayCanvas.addCanvas(imageCanvas);
 
  drawMatrix(&nWayCanvas, 20, 20, 50);
 
  nWayCanvas.flush();
 
  auto imageAlpha = offscreenAlphaSurface->makeImageSnapshot();
  auto image_ = offscreenSurface->makeImageSnapshot();
 
  if (!image_ || !imageAlpha) {
    SkDebugf("SNAPSHOT ERROR!\n");
    canvas->drawString("SNAPSHOT ERROR!", 20, 40, SkFont(nullptr, 12), txtpaint);
    return;
  }
 
  auto imageAlphaShader = imageAlpha->makeShader(SkSamplingOptions());
  auto imageShader = image_->makeShader(SkSamplingOptions());
 
  if (!imageAlphaShader || !imageShader) {
    SkDebugf("MAKE SHADER ERROR!\n");
    canvas->drawString("MAKE SHADER ERROR!", 20, 40, SkFont(nullptr, 12), txtpaint);
    return;
  }

  SkRuntimeShaderBuilder builder(sksl.effect);
  builder.child("input_") = imageShader;
  builder.child("inputAlpha") = imageAlphaShader;
 
  auto ourShader = builder.makeShader();
 
  if (!ourShader) {
    SkDebugf("COMBINE SHADER ERROR!\n");
    canvas->drawString("COMBINE SHADER ERROR!", 20, 40, SkFont(nullptr, 12), txtpaint);
    return;
  }
 
  SkPaint paint;
  paint.setBlendMode(SkBlendMode::kSrc);
  paint.setShader(ourShader);
  canvas->drawPaint(paint);
 
  SkDebugf("DRAWN!\n");
}
```
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

Clark Kent

unread,
Sep 2, 2022, 5:55:24 AM9/2/22
to skia-discuss
related to https://github.com/toptensoftware/RichTextKit/issues/54 but issue lies with Skia itself

i managed to get it debuggable (PDF and Debug)

but it seems half corrupted in PDF and WASM Skia Debugger (Web)

Clark Kent

unread,
Sep 2, 2022, 10:02:40 AM9/2/22
to skia-discuss
also https://github.com/toptensoftware/RichTextKit/issues/54#issuecomment-1235543333

so it may definitely be related to reproducable text geometry drawing

Clark Kent

unread,
Sep 6, 2022, 12:56:14 AM9/6/22
to skia-discuss
specifically this occurs in GPU via `translate(x, y); drawText(blob, 0, 0, paint);` and is solved via `drawText(blob, x, y, paint);` however this is not an adaquate solution since anything could be relying on the `translate` call

Clark Kent

unread,
Sep 7, 2022, 10:17:37 AM9/7/22
to skia-discuss
should this be filed as a bug?

Clark Kent

unread,
Sep 7, 2022, 10:46:43 PM9/7/22
to skia-discuss
might also occur on CPU? (on fiddle it does)

On Tuesday, 6 September 2022 at 14:56:14 UTC+10 Clark Kent wrote:

Clark Kent

unread,
Sep 7, 2022, 11:03:22 PM9/7/22
to skia-discuss
Reply all
Reply to author
Forward
0 new messages