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

Commit 0a417499 authored by Romain Guy's avatar Romain Guy
Browse files

Cleanup, better code reuse.

Change-Id: Ib86a7309ae579cce3b7cf464782c34e70a74c616
parent 5b53f918
Loading
Loading
Loading
Loading
+145 −157
Original line number Diff line number Diff line
@@ -562,82 +562,6 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
    drawColorRect(left, top, right, bottom, color, mode);
}

void OpenGLRenderer::renderShadow(const ShadowTexture* texture, float x, float y,
        SkXfermode::Mode mode) {
    const float sx = x - texture->left + mShadowDx;
    const float sy = y - texture->top + mShadowDy;

    const GLfloat a = ((mShadowColor >> 24) & 0xFF) / 255.0f;
    const GLfloat r = a * ((mShadowColor >> 16) & 0xFF) / 255.0f;
    const GLfloat g = a * ((mShadowColor >>  8) & 0xFF) / 255.0f;
    const GLfloat b = a * ((mShadowColor      ) & 0xFF) / 255.0f;

    GLuint textureUnit = 0;
    renderTextureAlpha8(texture, textureUnit, sx, sy, r, g, b, a, mode, false);
}

void OpenGLRenderer::renderTextureAlpha8(const Texture* texture, GLuint& textureUnit,
        float x, float y, float r, float g, float b, float a, SkXfermode::Mode mode,
        bool applyFilters) {
     // Describe the required shaders
     ProgramDescription description;
     description.hasTexture = true;
     description.hasAlpha8Texture = true;

     if (applyFilters) {
         if (mShader) {
             mShader->describe(description, mExtensions);
         }
         if (mColorFilter) {
             mColorFilter->describe(description, mExtensions);
         }
     }

     // Build and use the appropriate shader
     useProgram(mProgramCache.get(description));

     // Setup the blending mode
     chooseBlending(true, mode);
     bindTexture(texture->id, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
     glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);

     int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
     glEnableVertexAttribArray(texCoordsSlot);

     // Setup attributes
     glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
             gMeshStride, &mMeshVertices[0].position[0]);
     glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
             gMeshStride, &mMeshVertices[0].texture[0]);

     // Setup uniforms
     mModelView.loadTranslate(x, y, 0.0f);
     mModelView.scale(texture->width, texture->height, 1.0f);
     mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);

     glUniform4f(mCurrentProgram->color, r, g, b, a);

     textureUnit++;
     if (applyFilters) {
         // Setup attributes and uniforms required by the shaders
         if (mShader) {
             mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
         }
         if (mColorFilter) {
             mColorFilter->setupProgram(mCurrentProgram);
         }
     }

     // Draw the mesh
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);

     glDisableVertexAttribArray(texCoordsSlot);
}

#define kStdStrikeThru_Offset   (-6.0f / 21.0f)
#define kStdUnderline_Offset    (1.0f / 9.0f)
#define kStdUnderline_Thickness (1.0f / 18.0f)

void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
        float x, float y, SkPaint* paint) {
    if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
@@ -668,7 +592,12 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
        const ShadowTexture* shadow = mDropShadowCache.get(paint, text, bytesCount,
                count, mShadowRadius);
        const AutoTexture autoCleanup(shadow);
        renderShadow(shadow, x, y, mode);

        setupShadow(shadow, x, y, mode);

        // Draw the mesh
        glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
        glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords"));
    }

    uint32_t color = paint->getColor();
@@ -677,94 +606,19 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
    const GLfloat g = a * ((color >>  8) & 0xFF) / 255.0f;
    const GLfloat b = a * ((color      ) & 0xFF) / 255.0f;

    mModelView.loadIdentity();

    GLuint textureUnit = 0;
    // Needs to be set prior to calling FontRenderer::getTexture()
    glActiveTexture(gTextureUnits[textureUnit]);

    ProgramDescription description;
    description.hasTexture = true;
    description.hasAlpha8Texture = true;
    if (mShader) {
        mShader->describe(description, mExtensions);
    }
    if (mColorFilter) {
        mColorFilter->describe(description, mExtensions);
    }

    useProgram(mProgramCache.get(description));
    mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);

    // Text is always blended, no need to check the shader
    chooseBlending(true, mode);
    bindTexture(mFontRenderer.getTexture(), GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
    glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);

    int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
    glEnableVertexAttribArray(texCoordsSlot);

    // Always premultiplied
    glUniform4f(mCurrentProgram->color, r, g, b, a);

    textureUnit++;
    // Setup attributes and uniforms required by the shaders
    if (mShader) {
        mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
    }
    if (mColorFilter) {
        mColorFilter->setupProgram(mCurrentProgram);
    }
    setupTextureAlpha8(mFontRenderer.getTexture(), 0, 0, textureUnit, x, y, r, g, b, a,
            mode, false, true);

    const Rect& clip = mSnapshot->getLocalClip();
    mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(texCoordsSlot);

    // Handle underline and strike-through
    uint32_t flags = paint->getFlags();
    if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
        float underlineWidth = length;
        // If length is > 0.0f, we already measured the text for the text alignment
        if (length <= 0.0f) {
            underlineWidth = paint->measureText(text, bytesCount);
        }

        float offsetX = 0;
        switch (paint->getTextAlign()) {
            case SkPaint::kCenter_Align:
                offsetX = underlineWidth * 0.5f;
                break;
            case SkPaint::kRight_Align:
                offsetX = underlineWidth;
                break;
            default:
                break;
        }

        if (underlineWidth > 0.0f) {
            float textSize = paint->getTextSize();
            float height = textSize * kStdUnderline_Thickness;

            float left = x - offsetX;
            float top = 0.0f;
            float right = left + underlineWidth;
            float bottom = 0.0f;
    glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords"));

            if (flags & SkPaint::kUnderlineText_Flag) {
                top = y + textSize * kStdUnderline_Offset;
                bottom = top + height;
                drawRect(left, top, right, bottom, paint);
            }

            if (flags & SkPaint::kStrikeThruText_Flag) {
                top = y + textSize * kStdStrikeThru_Offset;
                bottom = top + height;
                drawRect(left, top, right, bottom, paint);
            }
        }
    }
    drawTextDecorations(text, bytesCount, length, x, y, paint);
}

void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
@@ -787,7 +641,12 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {

    const float x = texture->left - texture->offset;
    const float y = texture->top - texture->offset;
    renderTextureAlpha8(texture, textureUnit, x, y, r, g, b, a, mode, true);

    setupTextureAlpha8(texture, textureUnit, x, y, r, g, b, a, mode, true, true);

    // Draw the mesh
    glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
    glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords"));
}

///////////////////////////////////////////////////////////////////////////////
@@ -837,6 +696,135 @@ void OpenGLRenderer::setupShadow(float radius, float dx, float dy, int color) {
// Drawing implementation
///////////////////////////////////////////////////////////////////////////////

void OpenGLRenderer::setupShadow(const ShadowTexture* texture, float x, float y,
        SkXfermode::Mode mode) {
    const float sx = x - texture->left + mShadowDx;
    const float sy = y - texture->top + mShadowDy;

    const GLfloat a = ((mShadowColor >> 24) & 0xFF) / 255.0f;
    const GLfloat r = a * ((mShadowColor >> 16) & 0xFF) / 255.0f;
    const GLfloat g = a * ((mShadowColor >>  8) & 0xFF) / 255.0f;
    const GLfloat b = a * ((mShadowColor      ) & 0xFF) / 255.0f;

    GLuint textureUnit = 0;
    setupTextureAlpha8(texture, textureUnit, sx, sy, r, g, b, a, mode, true, false);
}

void OpenGLRenderer::setupTextureAlpha8(const Texture* texture, GLuint& textureUnit,
        float x, float y, float r, float g, float b, float a, SkXfermode::Mode mode,
        bool transforms, bool applyFilters) {
    setupTextureAlpha8(texture->id, texture->width, texture->height, textureUnit,
            x, y, r, g, b, a, mode, transforms, applyFilters);
}

void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t height,
        GLuint& textureUnit, float x, float y, float r, float g, float b, float a,
        SkXfermode::Mode mode, bool transforms, bool applyFilters) {
     // Describe the required shaders
     ProgramDescription description;
     description.hasTexture = true;
     description.hasAlpha8Texture = true;

     if (applyFilters) {
         if (mShader) {
             mShader->describe(description, mExtensions);
         }
         if (mColorFilter) {
             mColorFilter->describe(description, mExtensions);
         }
     }

     // Build and use the appropriate shader
     useProgram(mProgramCache.get(description));

     // Setup the blending mode
     chooseBlending(true, mode);
     bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
     glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);

     int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
     glEnableVertexAttribArray(texCoordsSlot);

     // Setup attributes
     glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
             gMeshStride, &mMeshVertices[0].position[0]);
     glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
             gMeshStride, &mMeshVertices[0].texture[0]);

     // Setup uniforms
     if (transforms) {
         mModelView.loadTranslate(x, y, 0.0f);
         mModelView.scale(width, height, 1.0f);
     } else {
         mModelView.loadIdentity();
     }
     mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);

     glUniform4f(mCurrentProgram->color, r, g, b, a);

     textureUnit++;
     if (applyFilters) {
         // Setup attributes and uniforms required by the shaders
         if (mShader) {
             mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
         }
         if (mColorFilter) {
             mColorFilter->setupProgram(mCurrentProgram);
         }
     }
}

#define kStdStrikeThru_Offset   (-6.0f / 21.0f)
#define kStdUnderline_Offset    (1.0f / 9.0f)
#define kStdUnderline_Thickness (1.0f / 18.0f)

void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float length,
        float x, float y, SkPaint* paint) {
    // Handle underline and strike-through
    uint32_t flags = paint->getFlags();
    if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
        float underlineWidth = length;
        // If length is > 0.0f, we already measured the text for the text alignment
        if (length <= 0.0f) {
            underlineWidth = paint->measureText(text, bytesCount);
        }

        float offsetX = 0;
        switch (paint->getTextAlign()) {
            case SkPaint::kCenter_Align:
                offsetX = underlineWidth * 0.5f;
                break;
            case SkPaint::kRight_Align:
                offsetX = underlineWidth;
                break;
            default:
                break;
        }

        if (underlineWidth > 0.0f) {
            float textSize = paint->getTextSize();
            float height = textSize * kStdUnderline_Thickness;

            float left = x - offsetX;
            float top = 0.0f;
            float right = left + underlineWidth;
            float bottom = 0.0f;

            if (flags & SkPaint::kUnderlineText_Flag) {
                top = y + textSize * kStdUnderline_Offset;
                bottom = top + height;
                drawRect(left, top, right, bottom, paint);
            }

            if (flags & SkPaint::kStrikeThruText_Flag) {
                top = y + textSize * kStdStrikeThru_Offset;
                bottom = top + height;
                drawRect(left, top, right, bottom, paint);
            }
        }
    }
}

void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
        int color, SkXfermode::Mode mode, bool ignoreTransform) {
    // If a shader is set, preserve only the alpha
+44 −5
Original line number Diff line number Diff line
@@ -226,17 +226,17 @@ private:
            GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0);

    /**
     * Renders the specified shadow.
     * Prepares the renderer to draw the specified shadow.
     *
     * @param texture The shadow texture
     * @param x The x coordinate of the shadow
     * @param y The y coordinate of the shadow
     * @param mode The blending mode
     */
    void renderShadow(const ShadowTexture* texture, float x, float y, SkXfermode::Mode mode);
    void setupShadow(const ShadowTexture* texture, float x, float y, SkXfermode::Mode mode);

    /**
     * Renders the specified Alpha8 texture as a rectangle.
     * Prepares the renderer to draw the specified Alpha8 texture as a rectangle.
     *
     * @param texture The texture to render with
     * @param textureUnit The texture unit to use, may be modified
@@ -247,11 +247,50 @@ private:
     * @param b The blue component of the color
     * @param a The alpha component of the color
     * @param mode The blending mode
     * @param transforms True if the matrix passed to the shader should be multiplied
     *        by the model-view matrix
     * @param applyFilters Whether or not to take color filters and
     *        shaders into account
     */
    void renderTextureAlpha8(const Texture* texture, GLuint& textureUnit, float x, float y,
            float r, float g, float b, float a, SkXfermode::Mode mode, bool applyFilters);
    void setupTextureAlpha8(const Texture* texture, GLuint& textureUnit, float x, float y,
            float r, float g, float b, float a, SkXfermode::Mode mode, bool transforms,
            bool applyFilters);

    /**
     * Prepares the renderer to draw the specified Alpha8 texture as a rectangle.
     *
     * @param texture The texture to render with
     * @param width The width of the texture
     * @param height The height of the texture
     * @param textureUnit The texture unit to use, may be modified
     * @param x The x coordinate of the rectangle to draw
     * @param y The y coordinate of the rectangle to draw
     * @param r The red component of the color
     * @param g The green component of the color
     * @param b The blue component of the color
     * @param a The alpha component of the color
     * @param mode The blending mode
     * @param transforms True if the matrix passed to the shader should be multiplied
     *        by the model-view matrix
     * @param applyFilters Whether or not to take color filters and
     *        shaders into account
     */
    void setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t height,
            GLuint& textureUnit, float x, float y, float r, float g, float b, float a,
            SkXfermode::Mode mode, bool transforms, bool applyFilters);

    /**
     * Draws text underline and strike-through if needed.
     *
     * @param text The text to decor
     * @param bytesCount The number of bytes in the text
     * @param length The length in pixels of the text, can be <= 0.0f to force a measurement
     * @param x The x coordinate where the text will be drawn
     * @param y The y coordinate where the text will be drawn
     * @param paint The paint to draw the text with
     */
    void drawTextDecorations(const char* text, int bytesCount, float length,
            float x, float y, SkPaint* paint);

    /**
     * Resets the texture coordinates stored in mMeshVertices. Setting the values
+9 −0
Original line number Diff line number Diff line
@@ -189,5 +189,14 @@
            </intent-filter>
        </activity>

        <activity
                android:name="StackActivity"
                android:label="_Stacks">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.test.hwui;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.StackView;

@SuppressWarnings({"UnusedDeclaration"})
public class StackActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        StackView stack = new StackView(this);
        stack.setAdapter(new ArrayAdapter<Drawable>(this, android.R.layout.simple_list_item_1,
                android.R.id.text1, new Drawable[] {
            getResources().getDrawable(R.drawable.sunset1),
            getResources().getDrawable(R.drawable.sunset2),
            getResources().getDrawable(R.drawable.sunset1),
            getResources().getDrawable(R.drawable.sunset2),
            getResources().getDrawable(R.drawable.sunset1),
            getResources().getDrawable(R.drawable.sunset2)                
        }) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ImageView image;
                if (convertView == null) {
                    image = new ImageView(StackActivity.this);
                } else {
                    image = (ImageView) convertView;
                }
                image.setImageDrawable(getItem(position % getCount()));
                return image;
            }
        });
        stack.setDisplayedChild(0);

        FrameLayout layout = new FrameLayout(this);
        layout.addView(stack, new FrameLayout.LayoutParams(500, 500, Gravity.CENTER));
        setContentView(layout);
    }
}