Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 318ae7bb authored by Romain Guy's avatar Romain Guy
Browse files

Take SkBitmap's stride into account when uploading textures

Bug #10151807

Change-Id: I7ba4804fa3619088fea70eb55f10519fff0bf5f0
parent 8e4b16d6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ public:
    inline bool has1BitStencil() const { return mHas1BitStencil; }
    inline bool has4BitStencil() const { return mHas4BitStencil; }
    inline bool hasNvSystemTime() const { return mHasNvSystemTime; }

    inline bool hasUnpackRowLength() const { return mVersionMajor >= 3; }
    inline bool hasPixelBufferObjects() const { return mVersionMajor >= 3; }
    inline bool hasOcclusionQueries() const { return mVersionMajor >= 3; }
    inline bool hasFloatTextures() const { return mVersionMajor >= 3; }
+20 −9
Original line number Diff line number Diff line
@@ -240,20 +240,20 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
    switch (bitmap->getConfig()) {
    case SkBitmap::kA8_Config:
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height,
                GL_UNSIGNED_BYTE, bitmap->getPixels());
        uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(),
                texture->width, texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels());
        texture->blend = true;
        break;
    case SkBitmap::kRGB_565_Config:
        glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
        uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->height,
                GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
        uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(),
                texture->width, texture->height, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
        texture->blend = false;
        break;
    case SkBitmap::kARGB_8888_Config:
        glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
        uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height,
                GL_UNSIGNED_BYTE, bitmap->getPixels());
        uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(),
                texture->width, texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels());
        // Do this after calling getPixels() to make sure Skia's deferred
        // decoding happened
        texture->blend = !bitmap->isOpaque();
@@ -293,17 +293,28 @@ void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
    SkCanvas canvas(rgbaBitmap);
    canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);

    uploadToTexture(resize, GL_RGBA, rgbaBitmap.rowBytesAsPixels(), height,
    uploadToTexture(resize, GL_RGBA, rgbaBitmap.rowBytesAsPixels(), width, height,
            GL_UNSIGNED_BYTE, rgbaBitmap.getPixels());
}

void TextureCache::uploadToTexture(bool resize, GLenum format, GLsizei width, GLsizei height,
        GLenum type, const GLvoid * data) {
void TextureCache::uploadToTexture(bool resize, GLenum format, GLsizei stride,
        GLsizei width, GLsizei height, GLenum type, const GLvoid * data) {
    // TODO: With OpenGL ES 2.0 we need to copy the bitmap in a temporary buffer
    //       if the stride doesn't match the width
    const bool useStride = stride != width && Extensions::getInstance().hasUnpackRowLength();
    if (useStride) {
        glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
    }

    if (resize) {
        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
    } else {
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
    }

    if (useStride) {
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    }
}

}; // namespace uirenderer
+2 −2
Original line number Diff line number Diff line
@@ -125,8 +125,8 @@ private:
    void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false);

    void uploadLoFiTexture(bool resize, SkBitmap* bitmap, uint32_t width, uint32_t height);
    void uploadToTexture(bool resize, GLenum format, GLsizei width, GLsizei height,
            GLenum type, const GLvoid * data);
    void uploadToTexture(bool resize, GLenum format, GLsizei stride,
            GLsizei width, GLsizei height, GLenum type, const GLvoid * data);

    void init();

+5 −5
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint3
    // OpenGL ES 3.0+ lets us specify the row length for unpack operations such
    // as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture.
    // With OpenGL ES 2.0 we have to upload entire stripes instead.
    mHasES3 = Extensions::getInstance().getMajorGlVersion() >= 3;
    mHasUnpackRowLength = Extensions::getInstance().hasUnpackRowLength();
}

CacheTexture::~CacheTexture() {
@@ -206,21 +206,21 @@ void CacheTexture::allocateTexture() {
bool CacheTexture::upload() {
    const Rect& dirtyRect = mDirtyRect;

    uint32_t x = mHasES3 ? dirtyRect.left : 0;
    uint32_t x = mHasUnpackRowLength ? dirtyRect.left : 0;
    uint32_t y = dirtyRect.top;
    uint32_t width = mHasES3 ? dirtyRect.getWidth() : mWidth;
    uint32_t width = mHasUnpackRowLength ? dirtyRect.getWidth() : mWidth;
    uint32_t height = dirtyRect.getHeight();

    // The unpack row length only needs to be specified when a new
    // texture is bound
    if (mHasES3) {
    if (mHasUnpackRowLength) {
        glPixelStorei(GL_UNPACK_ROW_LENGTH, mWidth);
    }

    mTexture->upload(x, y, width, height);
    setDirty(false);

    return mHasES3;
    return mHasUnpackRowLength;
}

void CacheTexture::setDirty(bool dirty) {
+1 −1
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ private:
    uint32_t mMaxQuadCount;
    Caches& mCaches;
    CacheBlock* mCacheBlocks;
    bool mHasES3;
    bool mHasUnpackRowLength;
    Rect mDirtyRect;
};