From f533e947035795a485344f4c270e16507f974901 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Tue, 14 Jan 2014 22:35:37 -0800 Subject: Support projection of DisplayLists onto ancestors. For now, ancestor views signal the acceptance of projections with a save(0x20)/restore pair. During the order traversal, each view with the save(0x20) code will collect descendent views with mProjectToContainedVolume (which still needs to be renamed) so that they can be drawn out of order later. - *Temporary* sample code added to HwAccelerationTest. - Note that a projected displaylist must not be clipped. Change-Id: I45c493e845961535b958d59c53e8aff3f8891d9f --- tests/HwAccelerationTest/AndroidManifest.xml | 9 ++ tests/HwAccelerationTest/res/layout/projection.xml | 36 +++++++ .../com/android/test/hwui/ProjectionActivity.java | 110 +++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 tests/HwAccelerationTest/res/layout/projection.xml create mode 100644 tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java (limited to 'tests/HwAccelerationTest') diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 6f774f8..0ad3456 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -858,5 +858,14 @@ + + + + + + + diff --git a/tests/HwAccelerationTest/res/layout/projection.xml b/tests/HwAccelerationTest/res/layout/projection.xml new file mode 100644 index 0000000..564201a --- /dev/null +++ b/tests/HwAccelerationTest/res/layout/projection.xml @@ -0,0 +1,36 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java new file mode 100644 index 0000000..51a6803 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java @@ -0,0 +1,110 @@ +package com.android.test.hwui; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.os.Bundle; + +import android.app.Activity; +import android.util.AttributeSet; +import android.view.DisplayList; +import android.view.View; +import android.widget.LinearLayout; + +public class ProjectionActivity extends Activity { + /** + * The content from this view should be projected in between the background of the + * ProjecteeLayout and its children, unclipped. + * + * This view doesn't clip to its bounds (because its parent has clipChildren=false) so that + * when it is projected onto the ProjecteeLayout, it draws outside its view bounds. + */ + public static class ProjectedView extends View { + private final Paint mPaint = new Paint(); + private final RectF mRectF = new RectF(); + + public ProjectedView(Context context) { + this(context, null); + } + + public ProjectedView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ProjectedView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + setOnClickListener(new OnClickListener() { + boolean toggle = false; + @Override + public void onClick(View v) { + toggle = !toggle; + setProject(toggle); + } + }); + } + + private void setProject(boolean value) { + DisplayList displayList = getDisplayList(); + if (displayList != null) { + displayList.setProjectToContainedVolume(value); + } + // NOTE: we can't invalidate ProjectedView for the redraw because: + // 1) the view won't preserve displayList properties that it doesn't know about + // 2) the damage rect won't be big enough + + // instead, twiddle properties on the container, so that enough area of the screen is + // redrawn without rerecording any DisplayLists. + container.setTranslationX(100f); + container.setTranslationX(0.0f); + } + + @Override + protected void onDraw(Canvas canvas) { + // TODO: set projection flag + final int w = getWidth(); + final int h = getHeight(); + mRectF.set(0, -h, w, 2 * h); + mPaint.setAntiAlias(true); + mPaint.setColor(0x5f00ff00); + canvas.drawOval(mRectF, mPaint); + } + } + + public static class ProjecteeLayout extends LinearLayout { + private final Paint mPaint = new Paint(); + private final RectF mRectF = new RectF(); + + public ProjecteeLayout(Context context) { + this(context, null); + } + + public ProjecteeLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ProjecteeLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + canvas.save(0x20); // secret save flag + mRectF.set(0, 0, getWidth(), getHeight()); + mPaint.setColor(0x5f000000); + canvas.drawOval(mRectF, mPaint); + canvas.restore(); + super.dispatchDraw(canvas); + } + } + + static View container; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.projection); + container = findViewById(R.id.container); + } +} -- cgit v1.1