I have an OpenGL application in which I want to render text using Skia. Specifically, I want to render the text into a texture, and use the texture in my code later on.
<Setup OpenGL>
auto context = GrContext::MakeGL();
auto info = SkImageInfo::MakeN32Premul(width, height);
auto surface = sk_sp(SkSurface::MakeRenderTarget(context.get(), SkBudgeted::kNo, info));
auto canvas = surface->getCanvas();
auto text_color = SkColor4f::FromColor(SkColorSetARGB(255, 0, 0, 255)); // text color is blue.
SkPaint paint2(text_color);
canvas->clear(SkColorSetARGB(255,0,255,0)); // clear with green color
auto text_blob = SkTextBlob::MakeFromString("Hello, World", SkFont(nullptr, 55));
canvas->drawTextBlob(text_blob.get(), 300, 100, paint2);
surface->flush(SkSurface::BackendSurfaceAccess::kPresent, GrFlushInfo());
auto texture = surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
GrGLTextureInfo texture_info;
if (!texture.isValid()) {
log_error("missing texture");
exit(1);
}
if (!texture.getGLTextureInfo(&texture_info)) {
log_error("missing texture info");
exit(1);
}
<Use texture_info.fID for rendering>
The issue is that the resulting texture is colored green, so I know that the canvas was cleared correctlly, but no text appears.
I would've thought that I made a mistake in rendering the text, but if I take a snapshot of the surface and save it to an image, the text does appear on the saved image.
auto snapI = surface->makeImageSnapshot();
auto pngImage = snapI->encodeToData();
SkFILEWStream out("foo.png");
(void)out.write(pngImage->data(), pngImage->size());
This results in a green image with a blue "Hello, World" written over it. I know that I can use an SkBitmap or load the SkImage to a texture, but this is a real-time application, and I don't want to incur the cost of CPU synchronization if it can be avoided.
It seems like the text isn't rendered to the backend texture. Is this supposed to happen? What am I missing?