Wie zeichnet man mit Skia SkBitmap Text auf eine EGL-Textur?

Ich suche nach einer Möglichkeit, mit der Skia-Bibliothek in C / C ++ Text in EGLTexture zu zeichnen. Ich plane, ein Programm auszuführen, das dies während des Startvorgangs auf der Android-Plattform ausführt, bevor SurfaceFlinger gestartet wird.

Bitte verweisen Sie mich nicht auf Java-Beispiele für Android, da dies nicht das ist, wonach ich suche. Ich behebe ein Problem mit der Benutzeroberfläche auf Bildpufferebene. Ich suche nach einer Möglichkeit, dies in C / C ++ mit nativen Android-Bibliotheken (Skia usw.) zu tun.

Ich habe ein Beispielprogramm, das ein Bild mit SkBitmap auf EGLTexture rendern kann. Ich konnte es auf dem Monitor anzeigen. Ich folgte demselben Beispiel und entwickelte eine Strategie wie diese. Aber es funktioniert nicht.

0) Löschen Sie den Bildschirm mit grüner Farbe
1) Erstellen Sie eine SkBitmap der Größe 640x480.
2) EGLTexture erstellen, die mit dem von SkBitmap.lockPixels () zurückgegebenen Pixelpuffer gesichert ist
3) Zeichnen Sie mit SkCanvas Text auf SkBitmap. Laden Sie die Bitmap in die oben angegebene Textur hoch. 4) Zeichne dann die Textur auf die aktuelle Oberfläche

Als Ausgangspunkt habe ich ein Boot-Animationsprogramm (von Android) verwendet. Wenn ich dieses Programm ausführe, sehe ich nur grüne Farbe. Ich habe nach Fehlern von EGL-Aufrufen gesucht. Sie scheinen alle erfolgreich zu sein. Danke für Ihre Hilfe

Veröffentlichte diese Frage in Google Groups. Brian von Google hat hier einige Hinweise:https://groups.google.com/d/topic/skia-discuss/aC5f6HB4gSU/discussion

Unten ist Code, der das Obige implementiert.

#define EXPECT_NO_GL_ERROR(stmt)  \
  do {  \
    stmt;  \
    const EGLint error_code = eglGetError();  \
    if (EGL_SUCCESS != error_code){  \
        LOGD("GLTest: GL error code %d at %s:%d", error_code, __FILE__, __LINE__); \
        __android_log_assert("GLTest", "GLtest", "GlTest"); \
    }\
  } while(0)

struct Texture
{
    GLint w;
    GLint h;
    GLuint id;
};
bool GLTest::frametest()
{
    Texture texFrame;

    // Paint screen with green color
    glShadeModel (GL_FLAT);
    glDisable (GL_DITHER);
    glDisable (GL_SCISSOR_TEST);
    glClearColor(0, 1, 0, 1);
    glClear (GL_COLOR_BUFFER_BIT);
    eglSwapBuffers(mDisplay, mSurface);

    SkGraphics::Init();
    SkBitmap bitmap;

    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 640, 480);
    bitmap.allocPixels();
    if (NO_ERROR != initTexture(&texFrame, bitmap))
    {
        LOGD("GLTest: Unable to create a texture that is backed by SkBitmap");
        return false;
    }
    SkCanvas canvas(bitmap);
    SkPaint textAttribs;

    textAttribs.setColor(0xFFFFFFFF);
    textAttribs.setTextSize(SkIntToScalar(24));

    const nsecs_t startTime = systemTime();
    int frame_count = 0;
    do
    {
        nsecs_t now = systemTime();
        double time = now - startTime;

        canvas.drawColor(0xFF0000FF);
        canvas.drawText("Hello world", strlen("Hello world"), 200, 400,
                textAttribs);
        initTexture(&texFrame, bitmap); // Upload bitmap into canvas
        glEnable (GL_BLEND);
        EXPECT_NO_GL_ERROR(glBindTexture(GL_TEXTURE_2D, texFrame.id));
        EXPECT_NO_GL_ERROR(glDrawTexiOES(0, 0, 0, texFrame.w, texFrame.h));
        EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
        if (res == EGL_FALSE)
            break;
        frame_count++;
        if (0 == (frame_count % 150))
            LOGD("GLTest: Completed %d frames", frame_count);
        // 12fps: don't animate too fast to preserve CPU
        const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
        if (sleepTime > 0)
            usleep(sleepTime);
    } while (!exitPending());

    return false;
}

status_t GLTest::initTexture(Texture* texture, SkBitmap &bitmap)
{
    bitmap.lockPixels();

    const int w = bitmap.width();
    const int h = bitmap.height();
    const void* p = bitmap.getPixels();

    GLint crop[4] =
    { 0, h, w, -h };
    texture->w = w;
    texture->h = h;

    EXPECT_NO_GL_ERROR(glGenTextures(1, &(texture->id)));
    EXPECT_NO_GL_ERROR(glBindTexture(GL_TEXTURE_2D, texture->id));

    switch (bitmap.getConfig())
    {
    case SkBitmap::kA8_Config:
        EXPECT_NO_GL_ERROR(
                glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, p));
        break;
    case SkBitmap::kARGB_4444_Config:
        EXPECT_NO_GL_ERROR(
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p));
        break;
    case SkBitmap::kARGB_8888_Config:
        EXPECT_NO_GL_ERROR(
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, p));
        break;
    case SkBitmap::kRGB_565_Config:
        EXPECT_NO_GL_ERROR(
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p));
        break;
    default:
        break;
    }

    EXPECT_NO_GL_ERROR(
            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop));
    EXPECT_NO_GL_ERROR(
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    EXPECT_NO_GL_ERROR(
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
    EXPECT_NO_GL_ERROR(
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
    EXPECT_NO_GL_ERROR(
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
    return NO_ERROR;
}

Antworten auf die Frage(1)

Ihre Antwort auf die Frage