Do not apply transforms when using drawColor().
This fixes an issue in the way the clip transformations were applied.
Change-Id: I91e7b5d15baf244d1280e48938282bb33609081d
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 40c80fa..ba5be03 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -88,6 +88,9 @@
void copyTo(float* v) const;
void copyTo(SkMatrix& v) const;
+ /**
+ * Does not apply rotations!
+ */
void mapRect(Rect& r) const;
float getTranslateX();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 9739b9b..12b0dea 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -406,7 +406,7 @@
}
bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
- bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
+ bool clipped = mSnapshot->clip(left, top, right, bottom);
if (clipped) {
mSnapshot->flags |= Snapshot::kFlagClipSet;
setScissorFromClip();
@@ -492,8 +492,8 @@
}
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
- const Rect& clip = mSnapshot->clipRect;
- drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode);
+ const Rect& clip = mSnapshot->getMappedClip();
+ drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) {
@@ -524,7 +524,7 @@
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
- int color, SkXfermode::Mode mode) {
+ int color, SkXfermode::Mode mode, bool ignoreTransform) {
const int alpha = (color >> 24) & 0xFF;
const GLfloat a = alpha / 255.0f;
const GLfloat r = ((color >> 16) & 0xFF) / 255.0f;
@@ -538,7 +538,12 @@
mModelView.scale(right - left, bottom - top, 1.0f);
const bool inUse = useShader(mDrawColorShader);
- mDrawColorShader->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+ if (!ignoreTransform) {
+ mDrawColorShader->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+ } else {
+ mat4 identity;
+ mDrawColorShader->set(mOrthoMatrix, mModelView, identity);
+ }
if (!inUse) {
const GLvoid* p = &gDrawColorVertices[0].position[0];
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 1165ab6..8083038 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -160,9 +160,10 @@
* @param bottom The bottom coordinate of the rectangle
* @param color The rectangle's ARGB color, defined as a packed 32 bits word
* @param mode The Skia xfermode to use
+ * @param ignoreTransform True if the current transform should be ignored
*/
void drawColorRect(float left, float top, float right, float bottom,
- int color, SkXfermode::Mode mode);
+ int color, SkXfermode::Mode mode, bool ignoreTransform = false);
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index ef9269f..7265d91 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -56,6 +56,8 @@
previous(s),
layer(NULL),
fbo(s->fbo) {
+ mappedClip.set(s->clipRect);
+ transform.mapRect(mappedClip);
}
/**
@@ -87,12 +89,20 @@
* Returns the current clip region mapped by the current transform.
*/
const Rect& getMappedClip() {
+ return mappedClip;
+ }
+
+ /**
+ * Intersects the current clip with the new clip rectangle.
+ */
+ bool clip(float left, float top, float right, float bottom) {
+ bool clipped = clipRect.intersect(left, top, right, bottom);
if (flags & kFlagDirtyTransform) {
flags &= ~kFlagDirtyTransform;
mappedClip.set(clipRect);
transform.mapRect(mappedClip);
}
- return mappedClip;
+ return clipped;
}
/**
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index f13cfaf..cb894f1 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -87,6 +87,15 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
+ <activity
+ android:name="RotationActivity"
+ android:label="_Rotation">
+ <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/MultisamplingActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/MultisamplingActivity.java
deleted file mode 100644
index 95b14aa..0000000
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/MultisamplingActivity.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.View;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.widget.FrameLayout;
-
-@SuppressWarnings({"UnusedDeclaration"})
-public class MultisamplingActivity extends Activity {
- private static final String LOG_TAG = "HwUi";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- DirtyBitmapView container = new DirtyBitmapView(this);
-
- ColorView color = new ColorView(this);
- container.addView(color, new DirtyBitmapView.LayoutParams(
- dipToPx(this, 100), dipToPx(this, 100), Gravity.CENTER));
-
- AlphaAnimation a = new AlphaAnimation(1.0f, 0.0f);
- a.setDuration(2000);
- a.setRepeatCount(Animation.INFINITE);
- a.setRepeatMode(Animation.REVERSE);
- color.startAnimation(a);
-
- setContentView(container);
- }
-
- @SuppressWarnings({"UnusedDeclaration"})
- static int dipToPx(Context c, int dip) {
- return (int) (c.getResources().getDisplayMetrics().density * dip + 0.5f);
- }
-
- static class ColorView extends View {
- ColorView(Context c) {
- super(c);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- canvas.drawRGB(0, 255, 0);
- }
- }
-
- static class DirtyBitmapView extends FrameLayout {
- private final Paint mPaint;
-
- DirtyBitmapView(Context c) {
- super(c);
- mPaint = new Paint();
- }
-
- @Override
- public void dispatchDraw(Canvas canvas) {
- 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());
- Log.d(LOG_TAG, "rejected = " + canvas.quickReject(100.0f, 100.0f, 110.0f, 110.0f,
- Canvas.EdgeType.BW));
- Log.d(LOG_TAG, "rejected = " + canvas.quickReject(25.0f, 5.0f, 30.0f, 10.0f,
- Canvas.EdgeType.BW));
- 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());
- Log.d(LOG_TAG, "rejected = " + canvas.quickReject(50.0f, 50.0f, 60.0f, 60.0f,
- Canvas.EdgeType.BW));
- Log.d(LOG_TAG, "rejected = " + canvas.quickReject(25.0f, 5.0f, 30.0f, 10.0f,
- Canvas.EdgeType.BW));
- 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());
- Log.d(LOG_TAG, "rejected = " + canvas.quickReject(80.0f, 80.0f, 90.0f, 90.0f,
- Canvas.EdgeType.BW));
- Log.d(LOG_TAG, "rejected = " + canvas.quickReject(25.0f, 5.0f, 30.0f, 10.0f,
- Canvas.EdgeType.BW));
- canvas.restore();
-
- canvas.save();
- 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);
-
- canvas.restore();
-
- final int restoreTo = canvas.save();
- canvas.saveLayerAlpha(0.0f, 100.0f, getWidth(), 150.0f, 127,
- Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
- mPaint.setColor(0xff0000ff);
- canvas.drawRect(0.0f, 100.0f, 40.0f, 150.0f, mPaint);
- mPaint.setColor(0xff00ffff);
- canvas.drawRect(40.0f, 100.0f, 140.0f, 150.0f, mPaint);
- mPaint.setColor(0xffff00ff);
- canvas.drawRect(140.0f, 100.0f, 240.0f, 150.0f, mPaint);
- canvas.restoreToCount(restoreTo);
-
- super.dispatchDraw(canvas);
- }
- }
-}
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/RotationActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/RotationActivity.java
new file mode 100644
index 0000000..e629cb8
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/RotationActivity.java
@@ -0,0 +1,63 @@
+/*
+ * 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.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class RotationActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ DrawingView container = new DrawingView(this);
+
+ setContentView(container);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ static int dipToPx(Context c, int dip) {
+ return (int) (c.getResources().getDisplayMetrics().density * dip + 0.5f);
+ }
+
+ static class DrawingView extends View {
+ private final Paint mPaint;
+
+ DrawingView(Context c) {
+ super(c);
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.save();
+ canvas.translate(dipToPx(getContext(), 400), dipToPx(getContext(), 200));
+ canvas.rotate(45.0f);
+ canvas.drawRGB(255, 255, 255);
+ mPaint.setColor(0xffff0000);
+ canvas.drawRect(-80.0f, -80.0f, 80.0f, 80.0f, mPaint);
+ canvas.drawRect(0.0f, 0.0f, 220.0f, 220.0f, mPaint);
+ canvas.restore();
+ }
+ }
+}