summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/GLES20Canvas.java5
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp39
-rw-r--r--libs/hwui/Matrix.cpp21
-rw-r--r--libs/hwui/Matrix.h12
-rw-r--r--libs/hwui/OpenGLRenderer.cpp177
-rw-r--r--libs/hwui/OpenGLRenderer.h79
-rw-r--r--libs/hwui/Rect.h20
-rw-r--r--libs/hwui/shaders/drawColor.frag11
-rw-r--r--libs/hwui/shaders/drawColor.vert16
-rw-r--r--telephony/java/com/android/internal/telephony/CallManager.java2
-rw-r--r--tests/HwAccelerationTest/src/com/google/android/test/hwui/HwUiActivity.java39
11 files changed, 395 insertions, 26 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 8df2e86..eb077cb 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -186,10 +186,11 @@ class GLES20Canvas extends Canvas {
@Override
public boolean getClipBounds(Rect bounds) {
- // TODO: Implement
- return false;
+ return nGetClipBounds(mRenderer, bounds);
}
+ private native boolean nGetClipBounds(int renderer, Rect bounds);
+
@Override
public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
// TODO: Implement
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 1ca172d..95476eb 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -22,9 +22,22 @@
#include <SkXfermode.h>
#include <OpenGLRenderer.h>
+#include <Rect.h>
+#include <ui/Rect.h>
namespace android {
+using namespace uirenderer;
+
+// ----------------------------------------------------------------------------
+// Java APIs
+// ----------------------------------------------------------------------------
+
+static struct {
+ jclass clazz;
+ jmethodID set;
+} gRectClassInfo;
+
// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
@@ -90,6 +103,17 @@ static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas,
return renderer->clipRect(float(left), float(top), float(right), float(bottom));
}
+static bool android_view_GLES20Renderer_getClipBounds(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jobject rect) {
+
+ const android::uirenderer::Rect& bounds(renderer->getClipBounds());
+
+ env->CallVoidMethod(rect, gRectClassInfo.set,
+ int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
+
+ return !bounds.isEmpty();
+}
+
// ----------------------------------------------------------------------------
// Transforms
// ----------------------------------------------------------------------------
@@ -153,6 +177,9 @@ static JNINativeMethod gMethods[] = {
{ "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF },
{ "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect },
+ { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
+ (void*) android_view_GLES20Renderer_getClipBounds },
+
{ "nTranslate", "(IFF)V", (void*) android_view_GLES20Renderer_translate },
{ "nRotate", "(IF)V", (void*) android_view_GLES20Renderer_rotate },
{ "nScale", "(IFF)V", (void*) android_view_GLES20Renderer_scale },
@@ -164,7 +191,19 @@ static JNINativeMethod gMethods[] = {
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Renderer_drawColor },
};
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className); \
+ var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+ var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
int register_android_view_GLES20Canvas(JNIEnv* env) {
+ FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
+ GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
+
return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index cbbce38..c097d7f 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "UIMatrix"
+#define LOG_TAG "Matrix"
#include <math.h>
#include <stdlib.h>
@@ -27,6 +27,7 @@
#include "Matrix.h"
namespace android {
+namespace uirenderer {
void Matrix4::loadIdentity() {
mMat[0] = 1.0f;
@@ -175,6 +176,21 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float
mMat[14] = -(far + near) / (far - near);
}
+#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)
+
+void Matrix4::mapRect(Rect& r) const {
+ const float sx = mMat[0];
+ const float sy = mMat[5];
+
+ const float tx = mMat[12];
+ const float ty = mMat[13];
+
+ MUL_ADD_STORE(r.left, sx, tx);
+ MUL_ADD_STORE(r.right, sx, tx);
+ MUL_ADD_STORE(r.top, sy, ty);
+ MUL_ADD_STORE(r.bottom, sy, ty);
+}
+
void Matrix4::dump() const {
LOGD("Matrix4[");
LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]);
@@ -184,4 +200,5 @@ void Matrix4::dump() const {
LOGD("]");
}
-};
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 80f3fd6..9bd289f 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -14,12 +14,15 @@
* limitations under the License.
*/
-#ifndef ANDROID_MATRIX_H
-#define ANDROID_MATRIX_H
+#ifndef ANDROID_UI_MATRIX_H
+#define ANDROID_UI_MATRIX_H
#include <SkMatrix.h>
+#include "Rect.h"
+
namespace android {
+namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Classes
@@ -83,6 +86,8 @@ public:
void copyTo(float* v) const;
void copyTo(SkMatrix& v) const;
+ void mapRect(Rect& r) const;
+
void dump() const;
private:
@@ -103,6 +108,7 @@ private:
typedef Matrix4 mat4;
+}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_MATRIX_H
+#endif // ANDROID_UI_MATRIX_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e19795e..575bc20 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <GLES2/gl2.h>
@@ -32,6 +33,129 @@
#include "Matrix.h"
namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+#define SOLID_WHITE { 1.0f, 1.0f, 1.0f, 1.0f }
+
+#define P(x, y) { x, y }
+
+///////////////////////////////////////////////////////////////////////////////
+// Globals
+///////////////////////////////////////////////////////////////////////////////
+
+const Vertex gDrawColorVertices[] = {
+ { P(0.0f, 0.0f), SOLID_WHITE },
+ { P(1.0f, 0.0f), SOLID_WHITE },
+ { P(0.0f, 1.0f), SOLID_WHITE },
+ { P(1.0f, 1.0f), SOLID_WHITE }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Shaders
+///////////////////////////////////////////////////////////////////////////////
+
+#define SHADER_SOURCE(name, source) const char* name = #source
+
+#include "shaders/drawColor.vert"
+#include "shaders/drawColor.frag"
+
+Program::Program(const char* vertex, const char* fragment) {
+ vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+
+ id = glCreateProgram();
+ glAttachShader(id, vertexShader);
+ glAttachShader(id, fragmentShader);
+ glLinkProgram(id);
+
+ GLint status;
+ glGetProgramiv(id, GL_LINK_STATUS, &status);
+ if (status != GL_TRUE) {
+ GLint infoLen = 0;
+ glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1) {
+ char* log = (char*) malloc(sizeof(char) * infoLen);
+ glGetProgramInfoLog(id, infoLen, 0, log);
+ LOGE("Error while linking shaders: %s", log);
+ delete log;
+ }
+ glDeleteProgram(id);
+ }
+}
+
+Program::~Program() {
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(id);
+}
+
+void Program::use() {
+ glUseProgram(id);
+}
+
+int Program::addAttrib(const char* name) {
+ int slot = glGetAttribLocation(id, name);
+ attributes.add(name, slot);
+ return slot;
+}
+
+int Program::getAttrib(const char* name) {
+ return attributes.valueFor(name);
+}
+
+int Program::addUniform(const char* name) {
+ int slot = glGetUniformLocation(id, name);
+ uniforms.add(name, slot);
+ return slot;
+}
+
+int Program::getUniform(const char* name) {
+ return uniforms.valueFor(name);
+}
+
+GLuint Program::buildShader(const char* source, GLenum type) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &source, 0);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE) {
+ // Some drivers return wrong values for GL_INFO_LOG_LENGTH
+ // use a fixed size instead
+ GLchar log[512];
+ glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
+ LOGE("Error while compiling shader: %s", log);
+ glDeleteShader(shader);
+ }
+
+ return shader;
+}
+
+DrawColorProgram::DrawColorProgram():
+ Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
+ position = addAttrib("position");
+ color = addAttrib("color");
+ projection = addUniform("projection");
+ modelView = addUniform("modelView");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Support
+///////////////////////////////////////////////////////////////////////////////
+
+const Rect& Snapshot::getMappedClip() {
+ if (flags & kFlagDirtyTransform) {
+ flags &= ~kFlagDirtyTransform;
+ mappedClip.set(clipRect);
+ transform.mapRect(mappedClip);
+ }
+ return mappedClip;
+}
///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
@@ -39,6 +163,8 @@ namespace android {
OpenGLRenderer::OpenGLRenderer() {
LOGD("Create OpenGLRenderer");
+
+ mDrawColorShader = new DrawColorProgram;
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -114,7 +240,6 @@ int OpenGLRenderer::saveSnapshot() {
}
bool OpenGLRenderer::restoreSnapshot() {
- // TODO: handle local transformations
bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;
mSaveCount--;
@@ -132,18 +257,22 @@ bool OpenGLRenderer::restoreSnapshot() {
void OpenGLRenderer::translate(float dx, float dy) {
mSnapshot->transform.translate(dx, dy, 0.0f);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::rotate(float degrees) {
mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::scale(float sx, float sy) {
mSnapshot->transform.scale(sx, sy, 1.0f);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
mSnapshot->transform.load(*matrix);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
@@ -153,6 +282,7 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
mat4 m(*matrix);
mSnapshot->transform.multiply(m);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
///////////////////////////////////////////////////////////////////////////////
@@ -160,12 +290,15 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::setScissorFromClip() {
- Rect* clip = &(mSnapshot->clipRect);
- glScissor(clip->left, clip->top, clip->getWidth(), clip->getHeight());
+ const Rect& clip = mSnapshot->getMappedClip();
+ glScissor(clip.left, clip.top, clip.getWidth(), clip.getHeight());
+}
+
+const Rect& OpenGLRenderer::getClipBounds() {
+ return mSnapshot->clipRect;
}
bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
- // TODO: take local translate transform into account
bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
if (clipped) {
mSnapshot->flags |= Snapshot::kFlagClipSet;
@@ -179,7 +312,41 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom)
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
- LOGD("Drawing color");
+ GLfloat a = ((color >> 24) & 0xFF) / 255.0f;
+ GLfloat r = ((color >> 16) & 0xFF) / 255.0f;
+ GLfloat g = ((color >> 8) & 0xFF) / 255.0f;
+ GLfloat b = ((color ) & 0xFF) / 255.0f;
+
+ // TODO Optimize this section
+ const Rect& clip = mSnapshot->getMappedClip();
+
+ mat4 modelView;
+ modelView.loadScale(clip.getWidth(), clip.getHeight(), 1.0f);
+ modelView.translate(clip.left, clip.top, 0.0f);
+
+ float matrix[16];
+ modelView.copyTo(matrix);
+ // TODO Optimize this section
+
+ mDrawColorShader->use();
+
+ glUniformMatrix4fv(mDrawColorShader->projection, 1, GL_FALSE, &mOrthoMatrix[0]);
+ glUniformMatrix4fv(mDrawColorShader->modelView, 1, GL_FALSE, &matrix[0]);
+
+ glEnableVertexAttribArray(mDrawColorShader->position);
+
+ GLsizei stride = sizeof(Vertex);
+ const GLvoid* p = &gDrawColorVertices[0].position[0];
+
+ glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, stride, p);
+ glVertexAttrib4f(mDrawColorShader->color, r, g, b, a);
+
+ GLsizei vertexCount = sizeof(gDrawColorVertices) / sizeof(Vertex);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
+
+ glDisableVertexAttribArray(mDrawColorShader->position);
+ glDisableVertexAttribArray(mDrawColorShader->color);
}
+}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 595768c..88cbc1c 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -14,18 +14,23 @@
* limitations under the License.
*/
-#ifndef ANDROID_OPENGL_RENDERER_H
-#define ANDROID_OPENGL_RENDERER_H
+#ifndef ANDROID_UI_OPENGL_RENDERER_H
+#define ANDROID_UI_OPENGL_RENDERER_H
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <SkMatrix.h>
#include <SkXfermode.h>
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include "Matrix.h"
#include "Rect.h"
namespace android {
+namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Support
@@ -36,14 +41,20 @@ public:
Snapshot() {
}
- Snapshot(const sp<Snapshot> s): transform(s->transform), clipRect(s->clipRect),
- flags(0), previous(s) {
+ Snapshot(const sp<Snapshot> s):
+ transform(s->transform),
+ clipRect(s->clipRect),
+ flags(kFlagDirtyTransform),
+ previous(s) {
}
enum Flags {
kFlagClipSet = 0x1,
+ kFlagDirtyTransform = 0x2,
};
+ const Rect& getMappedClip();
+
// Local transformations
mat4 transform;
@@ -55,7 +66,58 @@ public:
// Previous snapshot in the frames stack
sp<Snapshot> previous;
-}; // struct Snapshot
+
+private:
+ // Clipping rectangle mapped with the transform
+ Rect mappedClip;
+}; // class Snapshot
+
+struct Vertex {
+ float position[2];
+ float color[4];
+}; // struct Vertex
+
+typedef char* shader;
+
+class Program: public LightRefBase<Program> {
+public:
+ Program(const char* vertex, const char* fragment);
+ ~Program();
+
+ void use();
+
+protected:
+ int addAttrib(const char* name);
+ int getAttrib(const char* name);
+
+ int addUniform(const char* name);
+ int getUniform(const char* name);
+
+private:
+ GLuint buildShader(const char* source, GLenum type);
+
+ // Handle of the OpenGL program
+ GLuint id;
+
+ // Handles of the shaders
+ GLuint vertexShader;
+ GLuint fragmentShader;
+
+ // Keeps track of attributes and uniforms slots
+ KeyedVector<const char*, int> attributes;
+ KeyedVector<const char*, int> uniforms;
+}; // class Program
+
+class DrawColorProgram: public Program {
+public:
+ DrawColorProgram();
+
+ int position;
+ int color;
+
+ int projection;
+ int modelView;
+};
///////////////////////////////////////////////////////////////////////////////
// Renderer
@@ -82,6 +144,7 @@ public:
void getMatrix(SkMatrix* matrix);
void concatMatrix(SkMatrix* matrix);
+ const Rect& getClipBounds();
bool clipRect(float left, float top, float right, float bottom);
void drawColor(int color, SkXfermode::Mode mode);
@@ -104,8 +167,12 @@ private:
Snapshot mFirstSnapshot;
// Current state
sp<Snapshot> mSnapshot;
+
+ // Shaders
+ sp<DrawColorProgram> mDrawColorShader;
}; // class OpenGLRenderer
+}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_OPENGL_RENDERER_H
+#endif // ANDROID_UI_OPENGL_RENDERER_H
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 724bd1a..fcf11e9 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#ifndef ANDROID_RECT_H
-#define ANDROID_RECT_H
+#ifndef ANDROID_UI_RECT_H
+#define ANDROID_UI_RECT_H
namespace android {
+namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Structs
@@ -29,7 +30,19 @@ struct Rect {
float right;
float bottom;
- Rect(): left(0), top(0), right(0), bottom(0) { }
+ Rect():
+ left(0),
+ top(0),
+ right(0),
+ bottom(0) {
+ }
+
+ Rect(float left, float top, float right, float bottom):
+ left(left),
+ top(top),
+ right(right),
+ bottom(bottom) {
+ }
Rect(const Rect& r) {
set(r);
@@ -120,6 +133,7 @@ struct Rect {
}; // struct Rect
+}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_RECT_H
diff --git a/libs/hwui/shaders/drawColor.frag b/libs/hwui/shaders/drawColor.frag
new file mode 100644
index 0000000..f753abb
--- /dev/null
+++ b/libs/hwui/shaders/drawColor.frag
@@ -0,0 +1,11 @@
+SHADER_SOURCE(gDrawColorFragmentShader,
+
+precision mediump float;
+
+varying vec4 outColor;
+
+void main(void) {
+ gl_FragColor = outColor;
+}
+
+);
diff --git a/libs/hwui/shaders/drawColor.vert b/libs/hwui/shaders/drawColor.vert
new file mode 100644
index 0000000..fd3cb45
--- /dev/null
+++ b/libs/hwui/shaders/drawColor.vert
@@ -0,0 +1,16 @@
+SHADER_SOURCE(gDrawColorVertexShader,
+
+attribute vec4 position;
+attribute vec4 color;
+
+uniform mat4 projection;
+uniform mat4 modelView;
+
+varying vec4 outColor;
+
+void main(void) {
+ outColor = color;
+ gl_Position = projection * modelView * position;
+}
+
+);
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index c548349..1ebf68a 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -207,7 +207,7 @@ public final class CallManager {
* java.lang.Object) registerForPreciseCallStateChanged()}.
*
* @exception CallStateException if active call is ringing, waiting, or
- * dialing/alerting, or heldCall can�t be active.
+ * dialing/alerting, or heldCall can't be active.
* In these cases, this operation may not be performed.
*/
public void switchHoldingAndActive(Call heldCall) throws CallStateException {
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/HwUiActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/HwUiActivity.java
index d24f027..81b9357 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/HwUiActivity.java
+++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/HwUiActivity.java
@@ -18,14 +18,13 @@ package com.google.android.test.hwui;
import android.app.Activity;
import android.content.Context;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
+import android.util.Log;
import android.view.View;
-import static android.util.Log.d;
-
+@SuppressWarnings({"UnusedDeclaration"})
public class HwUiActivity extends Activity {
private static final String LOG_TAG = "HwUi";
@@ -42,15 +41,47 @@ public class HwUiActivity extends Activity {
}
static class DirtyBitmapView extends View {
+ private final Paint mPaint;
+
DirtyBitmapView(Context c) {
super(c);
+ mPaint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
- canvas.drawRGB(255, 0, 0);
+ canvas.drawRGB(255, 255, 255);
+
+ mPaint.setColor(0xffff0000);
+ canvas.drawRect(200.0f, 0.0f, 220.0f, 20.0f, mPaint);
+
+ canvas.save();
+ canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+ Log.d(LOG_TAG, "clipRect = " + canvas.getClipBounds());
+ canvas.restore();
+
+ canvas.save();
+ canvas.scale(2.0f, 2.0f);
+ canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+ Log.d(LOG_TAG, "clipRect = " + canvas.getClipBounds());
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(20.0f, 20.0f);
+ canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+ Log.d(LOG_TAG, "clipRect = " + canvas.getClipBounds());
+ canvas.restore();
+
+ canvas.scale(2.0f, 2.0f);
+ canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+
+ mPaint.setColor(0xff00ff00);
+ canvas.drawRect(0.0f, 0.0f, 20.0f, 20.0f, mPaint);
+
+ mPaint.setColor(0xff0000ff);
+ canvas.drawRect(20.0f, 0.0f, 40.0f, 20.0f, mPaint);
}
}
}