diff options
author | 2010-08-16 20:26:20 -0700 | |
---|---|---|
committer | 2010-08-16 20:26:20 -0700 | |
commit | 0a41749953f35d33f61b3119e3161a82bb5fa59e (patch) | |
tree | 3e0827c18c19e3ad8745ce133561be8a275f0345 | |
parent | 5b53f9186e7812c93bc578d18e92cb123481fcbc (diff) |
Cleanup, better code reuse.
Change-Id: Ib86a7309ae579cce3b7cf464782c34e70a74c616
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 302 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 49 | ||||
-rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 9 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java | 65 |
4 files changed, 263 insertions, 162 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index da5b9dd0097a..700355ad0b4c 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -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); + glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords")); - // 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); - } - } - } + 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 diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 948ff1336595..49143a521144 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -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 diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 181b4c861ef7..775dc249aed8 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -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> diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java new file mode 100644 index 000000000000..46c790c586d0 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java @@ -0,0 +1,65 @@ +/* + * 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); + } +} |