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

Commit e07f6eeb authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Add implementation for drawBitmap()."

parents 2ae5a4d9 c1396e93
Loading
Loading
Loading
Loading
+43 −15
Original line number Diff line number Diff line
@@ -54,10 +54,10 @@ static const GLsizei gDrawColorVertexCount = 4;
// This array is never used directly but used as a memcpy source in the
// OpenGLRenderer constructor
static const TextureVertex gDrawTextureVertices[] = {
        FV(0.0f, 0.0f, 0.0f, 1.0f),
        FV(1.0f, 0.0f, 1.0f, 1.0f),
        FV(0.0f, 1.0f, 0.0f, 0.0f),
        FV(1.0f, 1.0f, 1.0f, 0.0f)
        FV(0.0f, 0.0f, 0.0f, 0.0f),
        FV(1.0f, 0.0f, 1.0f, 0.0f),
        FV(0.0f, 1.0f, 0.0f, 1.0f),
        FV(1.0f, 1.0f, 1.0f, 1.0f)
};
static const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex);
static const GLsizei gDrawTextureVertexCount = 4;
@@ -208,7 +208,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
    resetDrawTextureTexCoords(u1, v1, u2, v1);

    drawTextureRect(layer.left, layer.top, layer.right, layer.bottom,
            current->texture, current->alpha, current->mode, true);
            current->texture, current->alpha, current->mode, true, true);

    resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f);

@@ -378,8 +378,33 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom)
// Drawing
///////////////////////////////////////////////////////////////////////////////

void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top, const SkPaint* paint) {
    LOGD("Drawing bitmap!");
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint) {
    Texture* texture = mTextureCache.get(bitmap);

    SkXfermode::Mode mode;
    int alpha;

    if (paint) {
        const bool isMode = SkXfermode::IsMode(paint->getXfermode(), &mode);
        if (!isMode) {
            // Assume SRC_OVER
            mode = SkXfermode::kSrcOver_Mode;
        }

        // Skia draws using the color's alpha channel if < 255
        // Otherwise, it uses the paint's alpha
        int color = paint->getColor();
        alpha = (color >> 24) & 0xFF;
        if (alpha == 255) {
            alpha = paint->getAlpha();
        }
    } else {
        mode = SkXfermode::kSrcOver_Mode;
        alpha = 255;
    }

    drawTextureRect(left, top, left + texture->width, top + texture->height, texture->id,
            alpha / 255.0f, mode, texture->blend, true);
}

void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -443,23 +468,26 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
}

void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
        GLuint texture, float alpha, SkXfermode::Mode mode, bool isPremultiplied) {
        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied) {
    mModelView.loadTranslate(left, top, 0.0f);
    mModelView.scale(right - left, bottom - top, 1.0f);

    mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]);

    if (blend || alpha < 1.0f || mode != SkXfermode::kSrcOver_Mode) {
        GLenum sourceMode = gBlends[mode].src;
        if (!isPremultiplied && sourceMode == GL_ONE) {
            sourceMode = GL_SRC_ALPHA;
        }

    // TODO: Try to disable blending when the texture is opaque and alpha == 1.0f
        glEnable(GL_BLEND);
        glBlendFunc(sourceMode, gBlends[mode].dst);
    }

    glBindTexture(GL_TEXTURE_2D, texture);

    // TODO handle tiling and filtering here

    glActiveTexture(GL_TEXTURE0);
    glUniform1i(mDrawTextureShader->sampler, 0);

+3 −2
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ public:
    bool quickReject(float left, float top, float right, float bottom);
    bool clipRect(float left, float top, float right, float bottom);

    void drawBitmap(const SkBitmap* bitmap, float left, float top, const SkPaint* paint);
    void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
    void drawColor(int color, SkXfermode::Mode mode);
    void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);

@@ -183,10 +183,11 @@ private:
     * @param texture The texture name to map onto the rectangle
     * @param alpha An additional translucency parameter, between 0.0f and 1.0f
     * @param mode The blending mode
     * @param blend True if the texture contains an alpha channel
     * @param isPremultiplied Indicates whether the texture has premultiplied alpha
     */
    void drawTextureRect(float left, float top, float right, float bottom, GLuint texture,
            float alpha, SkXfermode::Mode mode, bool isPremultiplied = false);
            float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied = false);

    /**
     * Resets the texture coordinates stored in mDrawTextureVertices. Setting the values
+20 −10
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ Texture* TextureCache::get(SkBitmap* bitmap) {
    Texture* texture = mCache.get(bitmap);
    if (!texture) {
        texture = new Texture;
        generateTexture(bitmap, texture);
        generateTexture(bitmap, texture, false);
        mCache.put(bitmap, texture);
    } else if (bitmap->getGenerationID() != texture->generation) {
        generateTexture(bitmap, texture, true);
@@ -58,7 +58,14 @@ void TextureCache::clear() {
}

void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
    SkAutoLockPixels alp(*bitmap);
    if (!bitmap->readyToDraw()) {
        LOGE("Cannot generate texture from bitmap");
        return;
    }

    if (!regenerate) {
        texture->generation = bitmap->getGenerationID();
        texture->width = bitmap->width();
        texture->height = bitmap->height();

@@ -66,25 +73,28 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
    }

    glBindTexture(GL_TEXTURE_2D, texture->id);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());

    switch (bitmap->getConfig()) {
    case SkBitmap::kRGB_565_Config:
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, texture->width, texture->height,
                0, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
        texture->blend = false;
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmap->rowBytesAsPixels(), texture->height, 0,
                GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
        break;
    case SkBitmap::kARGB_8888_Config:
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height,
                0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());
        texture->blend = true;
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height, 0,
                GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());
        break;
    default:
        break;
    }

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glBindTexture(GL_TEXTURE_2D, 0);
}

+3 −3
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
        <activity
                android:name="LayersActivity"
                android:label="_Layers"
                android:theme="@android:style/Theme.Translucent">
                android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
@@ -43,7 +43,7 @@
        <activity
                android:name="XfermodeActivity"
                android:label="_Xfermodes"
                android:theme="@android:style/Theme.Translucent">
                android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
@@ -53,7 +53,7 @@
        <activity
                android:name="BitmapsActivity"
                android:label="_Bitmaps"
                android:theme="@android:style/Theme.Translucent">
                android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
+12 −1
Original line number Diff line number Diff line
@@ -26,13 +26,24 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;

@SuppressWarnings({"UnusedDeclaration"})
public class BitmapsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new BitmapsView(this));
        final BitmapsView view = new BitmapsView(this);
        setContentView(view);
        
        ScaleAnimation a = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
                ScaleAnimation.RELATIVE_TO_SELF,0.5f);
        a.setDuration(2000);
        a.setRepeatCount(Animation.INFINITE);
        a.setRepeatMode(Animation.REVERSE);
        view.startAnimation(a);
    }

    static class BitmapsView extends View {