Add position information for DrawViews.

Summary: Previously, we had no information about the positioning of the view until after we had attached it.  We have the position information attached to the shadow node, but this attaches it to the DrawView as well.  It also removes the need for AbstractClippingDrawCommand.

Reviewed By: ahmedre

Differential Revision: D3609092
This commit is contained in:
Seth Kirby
2016-07-26 17:31:54 -07:00
committed by Ahmed El-Helw
parent ba56043715
commit 498fc63952
8 changed files with 194 additions and 129 deletions

View File

@@ -11,41 +11,51 @@ package com.facebook.react.flat;
import android.graphics.Canvas;
/* package */ final class DrawView extends AbstractClippingDrawCommand {
/* package */ final class DrawView extends AbstractDrawCommand {
/* package */ final int reactTag;
// Indicates if the DrawView is frozen. If it is frozen then any setting of the clip bounds
// should create a new DrawView.
private boolean mFrozen;
// Indicates whether this DrawView has been previously drawn. If it has been drawn, then we know
// that the bounds haven't changed, as a bounds change would trigger a new DrawView, which will
// set this to false for the new DrawView. Leaving this as package for direct access, but this
// should only be set from draw in DrawView, to avoid race conditions.
/* package */ boolean mPreviouslyDrawn;
// Indicates whether this DrawView has been previously mounted to a clipping FlatViewGroup. This
// lets us know that the bounds haven't changed, as a bounds change would trigger a new DrawView,
// which will set this to false for the new DrawView. This is safe, despite the dual access with
// FlatViewGroup, because the FlatViewGroup copy is only ever modified by the FlatViewGroup.
// Changing how this boolean is used should be handled with caution, as race conditions are the
// quickest way to create unreproducible super bugs.
/* package */ boolean mWasMounted;
public DrawView(int reactTag) {
this.reactTag = reactTag;
}
/**
* Similar to updateBoundsAndFreeze, but thread safe as the mounting flag is modified on the UI
* thread.
*
* @return A DrawView with the passed bounds and clipping bounds. If we can use the same
* DrawView, it will just be this, otherwise it will be a frozen copy.
*/
public DrawView collectDrawView(
float left,
float top,
float right,
float bottom,
float clipLeft,
float clipTop,
float clipRight,
float clipBottom) {
if (mFrozen) {
return clipBoundsMatch(clipLeft, clipTop, clipRight, clipBottom) ?
this :
new DrawView(reactTag).collectDrawView(clipLeft, clipTop, clipRight, clipBottom);
} else {
mFrozen = true;
setClipBounds(clipLeft, clipTop, clipRight, clipBottom);
return this;
DrawView drawView = (DrawView)
updateBoundsAndFreeze(left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom);
if (drawView != this) {
// It is very important that we unset this, as our spec is that newly created DrawViews are
// handled differently by the FlatViewGroup. This is needed because updateBoundsAndFreeze
// uses .clone(), so we maintain the previous state.
drawView.mWasMounted = false;
}
return drawView;
}
@Override
public void draw(FlatViewGroup parent, Canvas canvas) {
mPreviouslyDrawn = true;
onPreDraw(parent, canvas);
if (mNeedsClipping) {
canvas.save(Canvas.CLIP_SAVE_FLAG);
applyClipping(canvas);
@@ -56,6 +66,11 @@ import android.graphics.Canvas;
}
}
@Override
protected void onDraw(Canvas canvas) {
// no op as we override draw.
}
@Override
public void debugDraw(FlatViewGroup parent, Canvas canvas) {
parent.debugDrawNextChild(canvas);