modules/graphics/src/main/java/com/sun/scenario/effect/FilterEffect.java
Print this page
@@ -29,16 +29,17 @@
import com.sun.javafx.geom.BaseBounds;
import com.sun.javafx.geom.RectBounds;
import com.sun.javafx.geom.Rectangle;
import com.sun.javafx.geom.transform.BaseTransform;
import com.sun.javafx.geom.transform.NoninvertibleTransformException;
+import com.sun.scenario.effect.impl.state.RenderState;
/**
* The implementation base class for {@link Effect} subclasses that operate
* by filtering the inputs at the pixel level.
*/
-public abstract class FilterEffect extends Effect {
+public abstract class FilterEffect<T extends RenderState> extends Effect {
protected FilterEffect() {
super();
}
protected FilterEffect(Effect input) {
@@ -47,22 +48,18 @@
protected FilterEffect(Effect input1, Effect input2) {
super(input1, input2);
}
- public boolean operatesInUserSpace() {
- return false;
- }
-
+ @Override
public BaseBounds getBounds(BaseTransform transform,
Effect defaultInput)
{
int numinputs = getNumInputs();
- BaseTransform inputtx = transform;
- if (operatesInUserSpace()) {
- inputtx = BaseTransform.IDENTITY_TRANSFORM;
- }
+ RenderState rstate = getRenderState(null, transform, null,
+ null, defaultInput);
+ BaseTransform inputtx = rstate.getInputTransform(transform);
BaseBounds ret;
if (numinputs == 1) {
Effect input = getDefaultedInput(0, defaultInput);
ret = input.getBounds(inputtx, defaultInput);
} else {
@@ -71,20 +68,13 @@
Effect input = getDefaultedInput(i, defaultInput);
inputBounds[i] = input.getBounds(inputtx, defaultInput);
}
ret = combineBounds(inputBounds);
}
- if (inputtx != transform) {
- ret = transformBounds(transform, ret);
- }
- return ret;
+ return transformBounds(rstate.getResultTransform(transform), ret);
}
- protected abstract Rectangle getInputClip(int inputIndex,
- BaseTransform transform,
- Rectangle outputBounds);
-
protected static Rectangle untransformClip(BaseTransform transform,
Rectangle clip)
{
if (transform.isIdentity() || clip == null || clip.isEmpty()) {
return clip;
@@ -142,53 +132,78 @@
// we might as well do as little work as we can.
}
return transformedBounds;
}
+ /**
+ * Returns the object representing the rendering strategy and state for
+ * the filter operation characterized by the specified arguments.
+ * This call can also be used to get a state object for non-rendering
+ * cases like querying the bounds of an operation in which case the
+ * {@link FilterContext} object may be null.
+ * {@code outputClip} and {@code renderHelper} may always be null just
+ * as they may be null for a given filter operation.
+ *
+ * @param fctx the context object that would be used by the Renderer
+ * if this call is preparing for a render operation, or null
+ * @param transform the transform for the output of this operation
+ * @param outputClip the clip rectangle that may restrict this operation, or null
+ * @param renderHelper the rendering helper object that can be used to shortcut
+ * this operation under certain conditions, or null
+ * @param defaultInput the {@link Effect} to be used in place of any null inputs
+ * @return
+ */
+ public abstract T getRenderState(FilterContext fctx,
+ BaseTransform transform,
+ Rectangle outputClip,
+ Object renderHelper,
+ Effect defaultInput);
+
@Override
public ImageData filter(FilterContext fctx,
BaseTransform transform,
Rectangle outputClip,
Object renderHelper,
Effect defaultInput)
{
+ T rstate = getRenderState(fctx, transform, outputClip,
+ renderHelper, defaultInput);
int numinputs = getNumInputs();
ImageData inputDatas[] = new ImageData[numinputs];
- Rectangle inputClip;
- BaseTransform inputtx;
- if (operatesInUserSpace()) {
- inputClip = untransformClip(transform, outputClip);
- inputtx = BaseTransform.IDENTITY_TRANSFORM;
+ Rectangle filterClip;
+ BaseTransform inputtx = rstate.getInputTransform(transform);
+ BaseTransform resulttx = rstate.getResultTransform(transform);
+ if (resulttx.isIdentity()) {
+ filterClip = outputClip;
} else {
- inputClip = outputClip;
- inputtx = transform;
+ filterClip = untransformClip(resulttx, outputClip);
}
for (int i = 0; i < numinputs; i++) {
Effect input = getDefaultedInput(i, defaultInput);
inputDatas[i] =
input.filter(fctx, inputtx,
- getInputClip(i, inputtx, inputClip),
+ rstate.getInputClip(i, filterClip),
null, defaultInput);
if (!inputDatas[i].validate(fctx)) {
for (int j = 0; j <= i; j++) {
inputDatas[j].unref();
}
return new ImageData(fctx, null, null);
}
}
- ImageData ret = filterImageDatas(fctx, inputtx, inputClip, inputDatas);
+ ImageData ret = filterImageDatas(fctx, inputtx, filterClip, rstate, inputDatas);
for (int i = 0; i < numinputs; i++) {
inputDatas[i].unref();
}
- if (inputtx != transform) {
+ if (!resulttx.isIdentity()) {
if (renderHelper instanceof ImageDataRenderer) {
ImageDataRenderer renderer = (ImageDataRenderer) renderHelper;
- renderer.renderImage(ret, transform, fctx);
+ renderer.renderImage(ret, resulttx, fctx);
ret.unref();
ret = null;
} else {
- ret = ret.transform(transform);
+ ret = ret.transform(resulttx);
}
}
return ret;
}
@@ -203,7 +218,8 @@
}
protected abstract ImageData filterImageDatas(FilterContext fctx,
BaseTransform transform,
Rectangle outputClip,
+ T rstate,
ImageData... inputDatas);
}