Loading libs/hwui/OpenGLRenderer.cpp +145 −157 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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(); Loading @@ -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) { Loading @@ -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")); } /////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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 Loading libs/hwui/OpenGLRenderer.h +44 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading tests/HwAccelerationTest/AndroidManifest.xml +9 −0 Original line number Diff line number Diff line Loading @@ -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> tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java 0 → 100644 +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); } } Loading
libs/hwui/OpenGLRenderer.cpp +145 −157 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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(); Loading @@ -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) { Loading @@ -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")); } /////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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 Loading
libs/hwui/OpenGLRenderer.h +44 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
tests/HwAccelerationTest/AndroidManifest.xml +9 −0 Original line number Diff line number Diff line Loading @@ -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>
tests/HwAccelerationTest/src/com/google/android/test/hwui/StackActivity.java 0 → 100644 +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); } }