summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-03-21 13:12:28 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-03-21 13:12:28 -0700
commit43e7aeb37e1d4d86eb89a0a5f620d148289d1986 (patch)
treececd7e845d37ad879e6cae6b30c7e4dd6eeaab54
parent5bb357f4ccdb573efbe1476a7f20e82f454b3a93 (diff)
parented6fcb034b44d9a6ac2fc72fee6030417811f234 (diff)
downloadframeworks_base-43e7aeb37e1d4d86eb89a0a5f620d148289d1986.zip
frameworks_base-43e7aeb37e1d4d86eb89a0a5f620d148289d1986.tar.gz
frameworks_base-43e7aeb37e1d4d86eb89a0a5f620d148289d1986.tar.bz2
Merge "Add support for drawPoint() and drawPoints()."
-rw-r--r--core/java/android/view/GLES20Canvas.java15
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp10
-rw-r--r--libs/hwui/DisplayListRenderer.cpp14
-rw-r--r--libs/hwui/DisplayListRenderer.h2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp52
-rw-r--r--libs/hwui/OpenGLRenderer.h3
-rw-r--r--libs/hwui/ProgramCache.cpp42
-rw-r--r--libs/hwui/ProgramCache.h13
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java32
9 files changed, 168 insertions, 15 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index d841419..8621de3 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -773,19 +773,24 @@ class GLES20Canvas extends HardwareCanvas {
public void drawPoint(float x, float y, Paint paint) {
mPoint[0] = x;
mPoint[1] = y;
- drawPoints(mPoint, 0, 1, paint);
+ drawPoints(mPoint, 0, 2, paint);
}
@Override
- public void drawPoints(float[] pts, int offset, int count, Paint paint) {
- // TODO: Implement
+ public void drawPoints(float[] pts, Paint paint) {
+ drawPoints(pts, 0, pts.length, paint);
}
@Override
- public void drawPoints(float[] pts, Paint paint) {
- drawPoints(pts, 0, pts.length / 2, paint);
+ public void drawPoints(float[] pts, int offset, int count, Paint paint) {
+ int modifiers = setupModifiers(paint);
+ nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
+ private static native void nDrawPoints(int renderer, float[] points,
+ int offset, int count, int paint);
+
@Override
public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
// TODO: Implement
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index d6d3e4f..a4931ac 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -366,6 +366,13 @@ static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz,
}
}
+static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jfloatArray points, jint offset, jint count, SkPaint* paint) {
+ jfloat* storage = env->GetFloatArrayElements(points, NULL);
+ renderer->drawPoints(storage + offset, count, paint);
+ env->ReleaseFloatArrayElements(points, storage, 0);
+}
+
static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, SkPath* path, SkPaint* paint) {
renderer->drawPath(path, paint);
@@ -374,9 +381,7 @@ static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jfloatArray points, jint offset, jint count, SkPaint* paint) {
jfloat* storage = env->GetFloatArrayElements(points, NULL);
-
renderer->drawLines(storage + offset, count, paint);
-
env->ReleaseFloatArrayElements(points, storage, 0);
}
@@ -645,6 +650,7 @@ static JNINativeMethod gMethods[] = {
{ "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawOval", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawOval },
{ "nDrawArc", "(IFFFFFFZI)V", (void*) android_view_GLES20Canvas_drawArc },
+ { "nDrawPoints", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawPoints },
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f2f983f..bf1182c 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -53,6 +53,7 @@ const char* DisplayList::OP_NAMES[] = {
"DrawArc",
"DrawPath",
"DrawLines",
+ "DrawPoints",
"DrawText",
"ResetShader",
"SetupShader",
@@ -441,6 +442,13 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
renderer.drawLines(points, count, getPaint());
}
break;
+ case DrawPoints: {
+ int count = 0;
+ float* points = getFloats(count);
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
+ renderer.drawPoints(points, count, getPaint());
+ }
+ break;
case DrawText: {
getText(&text);
int count = getInt();
@@ -787,6 +795,12 @@ void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
addPaint(paint);
}
+void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+ addOp(DisplayList::DrawPoints);
+ addFloats(points, count);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint) {
addOp(DisplayList::DrawText);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 8773cb5..da57e4a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -89,6 +89,7 @@ public:
DrawArc,
DrawPath,
DrawLines,
+ DrawPoints,
DrawText,
ResetShader,
SetupShader,
@@ -264,6 +265,7 @@ public:
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
void drawLines(float* points, int count, SkPaint* paint);
+ void drawPoints(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
void resetShader();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index a711289..6c454a4 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -879,6 +879,11 @@ void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
mDescription.hasAlpha8Texture = isAlpha8;
}
+void OpenGLRenderer::setupDrawPoint(float pointSize) {
+ mDescription.isPoint = true;
+ mDescription.pointSize = pointSize;
+}
+
void OpenGLRenderer::setupDrawColor(int color) {
setupDrawColor(color, (color >> 24) & 0xFF);
}
@@ -987,6 +992,11 @@ void OpenGLRenderer::setupDrawModelView(float left, float top, float right, floa
}
}
+void OpenGLRenderer::setupDrawPointUniforms() {
+ int slot = mCaches.currentProgram->getUniform("pointSize");
+ glUniform1f(slot, mDescription.pointSize);
+}
+
void OpenGLRenderer::setupDrawColorUniforms() {
if (mColorSet || (mShader && mSetShaderColor)) {
mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
@@ -1446,6 +1456,48 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
}
}
+void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ // TODO: The paint's cap style defines whether the points are square or circular
+ // TODO: Handle AA for round points
+
+ // A stroke width of 0 has a special meaningin Skia:
+ // it draws an unscaled 1px point
+ const bool isHairLine = paint->getStrokeWidth() == 0.0f;
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ int verticesCount = count >> 1;
+ int generatedVerticesCount = 0;
+
+ TextureVertex pointsData[verticesCount];
+ TextureVertex* vertex = &pointsData[0];
+
+ setupDraw();
+ setupDrawPoint(isHairLine ? 1.0f : paint->getStrokeWidth());
+ setupDrawColor(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(mode);
+ setupDrawProgram();
+ setupDrawModelViewIdentity();
+ setupDrawColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawPointUniforms();
+ setupDrawShaderIdentityUniforms();
+ setupDrawMesh(vertex);
+
+ for (int i = 0; i < count; i += 2) {
+ TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
+ generatedVerticesCount++;
+ }
+
+ glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
+}
+
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
// No need to check against the clip, we fill the clip region
if (mSnapshot->isIgnored()) return;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 402563c..4b93b80 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -119,6 +119,7 @@ public:
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
virtual void drawLines(float* points, int count, SkPaint* paint);
+ virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint);
@@ -424,6 +425,7 @@ private:
* Various methods to setup OpenGL rendering.
*/
void setupDrawWithTexture(bool isAlpha8 = false);
+ void setupDrawPoint(float pointSize);
void setupDrawColor(int color);
void setupDrawColor(int color, int alpha);
void setupDrawColor(float r, float g, float b, float a);
@@ -442,6 +444,7 @@ private:
bool ignoreTransform = false, bool ignoreModelView = false);
void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
bool ignoreTransform = false);
+ void setupDrawPointUniforms();
void setupDrawColorUniforms();
void setupDrawPureColorUniforms();
void setupDrawShaderIdentityUniforms();
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 0b6c7b5..2562306 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -41,6 +41,8 @@ const char* gVS_Header_Attributes_TexCoords =
"attribute vec2 texCoords;\n";
const char* gVS_Header_Uniforms =
"uniform mat4 transform;\n";
+const char* gVS_Header_Uniforms_IsPoint =
+ "uniform float pointSize;\n";
const char* gVS_Header_Uniforms_HasGradient[3] = {
// Linear
"uniform mat4 screenSpace;\n",
@@ -56,6 +58,8 @@ const char* gVS_Header_Varyings_HasTexture =
"varying vec2 outTexCoords;\n";
const char* gVS_Header_Varyings_HasBitmap =
"varying vec2 outBitmapTexCoords;\n";
+const char* gVS_Header_Varyings_PointHasBitmap =
+ "varying vec2 outPointBitmapTexCoords;\n";
const char* gVS_Header_Varyings_HasGradient[3] = {
// Linear
"varying vec2 linear;\n",
@@ -78,8 +82,12 @@ const char* gVS_Main_OutGradient[3] = {
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
+const char* gVS_Main_OutPointBitmapTexCoords =
+ " outPointBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
" gl_Position = transform * position;\n";
+const char* gVS_Main_PointSize =
+ " gl_PointSize = pointSize;\n";
const char* gVS_Footer =
"}\n\n";
@@ -93,6 +101,9 @@ const char* gFS_Header =
"precision mediump float;\n\n";
const char* gFS_Uniforms_Color =
"uniform vec4 color;\n";
+const char* gFS_Header_Uniforms_PointHasBitmap =
+ "uniform vec2 textureDimension;\n"
+ "uniform float pointSize;\n";
const char* gFS_Uniforms_TextureSampler =
"uniform sampler2D sampler;\n";
const char* gFS_Uniforms_GradientSampler[3] = {
@@ -121,6 +132,10 @@ const char* gFS_Main =
"\nvoid main(void) {\n"
" lowp vec4 fragColor;\n";
+const char* gFS_Main_PointBitmapTexCoords =
+ " vec2 outBitmapTexCoords = outPointBitmapTexCoords + "
+ "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
+
// Fast cases
const char* gFS_Fast_SingleColor =
"\nvoid main(void) {\n"
@@ -347,6 +362,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.hasBitmap) {
shader.append(gVS_Header_Uniforms_HasBitmap);
}
+ if (description.isPoint) {
+ shader.append(gVS_Header_Uniforms_IsPoint);
+ }
// Varyings
if (description.hasTexture) {
shader.append(gVS_Header_Varyings_HasTexture);
@@ -355,7 +373,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Header_Varyings_HasBitmap);
+ shader.append(description.isPoint ?
+ gVS_Header_Varyings_PointHasBitmap :
+ gVS_Header_Varyings_HasBitmap);
}
// Begin the shader
@@ -367,7 +387,12 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Main_OutGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Main_OutBitmapTexCoords);
+ shader.append(description.isPoint ?
+ gVS_Main_OutPointBitmapTexCoords :
+ gVS_Main_OutBitmapTexCoords);
+ }
+ if (description.isPoint) {
+ shader.append(gVS_Main_PointSize);
}
// Output transformed position
shader.append(gVS_Main_Position);
@@ -399,7 +424,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Header_Varyings_HasBitmap);
+ shader.append(description.isPoint ?
+ gVS_Header_Varyings_PointHasBitmap :
+ gVS_Header_Varyings_HasBitmap);
}
// Uniforms
@@ -417,9 +444,13 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.hasGradient) {
shader.append(gFS_Uniforms_GradientSampler[description.gradientType]);
}
+ if (description.hasBitmap && description.isPoint) {
+ shader.append(gFS_Header_Uniforms_PointHasBitmap);
+ }
// Optimization for common cases
- if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone) {
+ if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone &&
+ !description.isPoint) {
bool fast = false;
const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -507,6 +538,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gFS_Main_FetchGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ if (description.isPoint) {
+ shader.append(gFS_Main_PointBitmapTexCoords);
+ }
if (!description.isBitmapNpot) {
shader.append(gFS_Main_FetchBitmap);
} else {
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index ead5b92..737d91b 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -71,7 +71,9 @@ namespace uirenderer {
#define PROGRAM_BITMAP_WRAPT_SHIFT 11
#define PROGRAM_GRADIENT_TYPE_SHIFT 33
-#define PROGRAM_MODULATE 35
+#define PROGRAM_MODULATE_SHIFT 35
+
+#define PROGRAM_IS_POINT_SHIFT 36
///////////////////////////////////////////////////////////////////////////////
// Types
@@ -135,6 +137,9 @@ struct ProgramDescription {
SkXfermode::Mode framebufferMode;
bool swapSrcDst;
+ bool isPoint;
+ float pointSize;
+
/**
* Resets this description. All fields are reset back to the default
* values they hold after building a new instance.
@@ -162,6 +167,9 @@ struct ProgramDescription {
framebufferMode = SkXfermode::kClear_Mode;
swapSrcDst = false;
+
+ isPoint = false;
+ pointSize = 0.0f;
}
/**
@@ -223,7 +231,8 @@ struct ProgramDescription {
}
key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
- if (modulate) key |= programid(0x1) << PROGRAM_MODULATE;
+ if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
+ if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
return key;
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
index 8ca842e..4233367 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
@@ -16,6 +16,7 @@
package com.android.test.hwui;
+import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
@@ -29,13 +30,26 @@ import android.view.View;
@SuppressWarnings({"UnusedDeclaration"})
public class LinesActivity extends Activity {
+ private ObjectAnimator mAnimator;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setBackgroundDrawable(new ColorDrawable(0xffffffff));
final LinesView view = new LinesView(this);
- //view.setAlpha(0.80f);
setContentView(view);
+
+ mAnimator = ObjectAnimator.ofFloat(view, "offset", 0.0f, 15.0f);
+ mAnimator.setDuration(1500);
+ mAnimator.setRepeatCount(ObjectAnimator.INFINITE);
+ mAnimator.setRepeatMode(ObjectAnimator.REVERSE);
+ mAnimator.start();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mAnimator.cancel();
}
public static class LinesView extends View {
@@ -50,6 +64,8 @@ public class LinesActivity extends Activity {
private final Paint mAlphaPaint;
private final Paint mHairLinePaint;
+ private float mOffset;
+
public LinesView(Context c) {
super(c);
@@ -89,11 +105,16 @@ public class LinesActivity extends Activity {
352.0f, 400.0f, 352.0f, 500.0f
};
}
+
+ public void setOffset(float offset) {
+ mOffset = offset;
+ invalidate();
+ }
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
-
+
canvas.save();
canvas.translate(100.0f, 20.0f);
@@ -103,6 +124,12 @@ public class LinesActivity extends Activity {
mLargePaint.setShader(mShader);
canvas.drawLine(42.0f, 0.0f, 222.0f, 400.0f, mLargePaint);
+ for (int x = 0; x < 20; x++) {
+ for (int y = 0; y < 20; y++) {
+ canvas.drawPoint(500.0f + x * (15.0f + mOffset),
+ y * (15.0f + mOffset), mLargePaint);
+ }
+ }
mLargePaint.setShader(null);
canvas.drawLines(mPoints, mAlphaPaint);
@@ -120,6 +147,7 @@ public class LinesActivity extends Activity {
canvas.restore();
+ canvas.save();
canvas.scale(10.0f, 10.0f);
canvas.drawLine(50.0f, 40.0f, 10.0f, 40.0f, mSmallPaint);
canvas.drawLine(10.0f, 50.0f, 50.0f, 50.0f, mSmallPaint);