package com.glview.hwui;
import com.glview.graphics.Rect;
import com.glview.graphics.Region;
import com.glview.pool.Pool;
import com.glview.pool.Poolable;
import com.glview.util.MatrixUtil;
public class Snapshot implements Poolable {
static Pool<Snapshot> sPool = new Pool<Snapshot>(false);
/**
* Indicates that the clip region was modified. When this
* snapshot is restored so must the clip.
*/
public final static int kFlagClipSet = 0x1;
/**
* Indicates that this snapshot was created when saving
* a new layer.
*/
public final static int kFlagIsLayer = 0x2;
/**
* Indicates that this snapshot is a special type of layer
* backed by an FBO. This flag only makes sense when the
* flag kFlagIsLayer is also set.
*
* Viewport has been modified to fit the new Fbo, and must be
* restored when this snapshot is restored.
*/
public final static int kFlagIsFboLayer = 0x4;
/**
* Indicates that this snapshot or an ancestor snapshot is
* an FBO layer.
*/
public final static int kFlagFboTarget = 0x8;
Snapshot previous;
int flags;
public static Snapshot obtain(Snapshot previous, int saveFlags) {
Snapshot snapshot = (Snapshot) sPool.poll(Snapshot.class);
snapshot.save(previous, saveFlags);
return snapshot;
}
private void save(Snapshot s, int saveFlags) {
flags = 0;
this.previous = s;
alpha = previous.alpha;
if ((saveFlags & GLCanvas.SAVE_FLAG_MATRIX) != 0) {
System.arraycopy(s.transform, 0, mTransformRoot, 0, mTransformRoot.length);
transform = mTransformRoot;
} else {
transform = s.transform;
}
if ((saveFlags & GLCanvas.SAVE_FLAG_CLIP) != 0) {
mClipRectRoot.set(s.clipRect);
clipRect = mClipRectRoot;
} else {
clipRect = s.clipRect;
}
if ((s.flags & kFlagFboTarget) != 0) {
flags |= kFlagFboTarget;
}
}
public float[] getTransformation() {
return transform;
}
float mTransformRoot[] = new float[48];
Rect mClipRectRoot = new Rect();
float alpha = 1;
float transform[] = mTransformRoot;
Rect clipRect = mClipRectRoot;
static ThreadLocal<Rect> sThreadLocalRect = new ThreadLocal<Rect>() {
protected Rect initialValue() {
return new Rect();
};
};
boolean clip(float left, float top, float right, float bottom, Region.Op op) {
Rect r = sThreadLocalRect.get();
r.set((int) left, (int) top, (int) right, (int) bottom);
MatrixUtil.mapRect(transform, r);
return clipTransformed(r, op);
}
boolean clipTransformed(Rect r, Region.Op op) {
boolean clipped = false;
switch (op) {
case INTERSECT: {
clipped = clipRect.intersect(r);
if (!clipped) {
clipRect.setEmpty();
clipped = true;
}
break;
}
case REPLACE: {
setClip(r.left, r.top, r.right, r.bottom);
clipped = true;
break;
}
default: {
break;
}
}
if (clipped) {
flags |= kFlagClipSet;
}
return clipped;
}
void setClip(int left, int top, int right, int bottom) {
clipRect.set(left, top, right, bottom);
flags |= kFlagClipSet;
}
public void recycle() {
previous = null;
sPool.push(this);
}
}