/*
 * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.scenario.effect;

import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;
import com.sun.scenario.effect.impl.Renderer;

A buffer that contains floating point data, intended for use as a parameter to effects such as DisplacementMap.
/** * A buffer that contains floating point data, intended for use as a parameter * to effects such as {@code DisplacementMap}. */
public class FloatMap { private final int width; private final int height; private final FloatBuffer buf; private boolean cacheValid;
Constructs a new FloatMap of the given width and height.
Params:
  • width – the width of the map, in pixels
  • height – the height of the map, in pixels
Throws:
/** * Constructs a new {@code FloatMap} of the given width and height. * * @param width the width of the map, in pixels * @param height the height of the map, in pixels * @throws IllegalArgumentException if either {@code width} or * {@code height} is outside the range [1, 4096] */
public FloatMap(int width, int height) { if (width <= 0 || width > 4096 || height <= 0 || height > 4096) { throw new IllegalArgumentException("Width and height must be in the range [1, 4096]"); } this.width = width; this.height = height; int size = width * height * 4; // We allocate a heap-based (indirect) FloatBuffer here because // some Decora backends aren't yet prepared to deal with direct // FloatBuffers (and to that end we've exposed the getData() method, // whose return value is float[]). Note that we use wrap() instead of // allocate() since the latter is not supported on CDC (specifically // the NIO subset from JSR 239). The byte order of the FloatBuffer // will be the native order of the underlying hardware, which is what // the various Decora backends expect. this.buf = FloatBuffer.wrap(new float[size]); }
Returns the width of the map, in pixels.
Returns:the width of the map, in pixels
/** * Returns the width of the map, in pixels. * * @return the width of the map, in pixels */
public int getWidth() { return width; }
Returns the height of the map, in pixels.
Returns:the height of the map, in pixels
/** * Returns the height of the map, in pixels. * * @return the height of the map, in pixels */
public int getHeight() { return height; } public float[] getData() { // we only use heap-based FloatBuffers (see comment in constructor // above) so the following is safe return buf.array(); } public FloatBuffer getBuffer() { return buf; }
Gets the sample for a specific band from the given (x,y) location.
Params:
  • x – the x location
  • y – the y location
  • band – the band to get (must be 1, 2, 3, or 4)
Returns:the sample of the specified band at the specified location
/** * Gets the sample for a specific band from the given {@code (x,y)} location. * * @param x the x location * @param y the y location * @param band the band to get (must be 1, 2, 3, or 4) * @return the sample of the specified band at the specified location */
public float getSample(int x, int y, int band) { return buf.get(((x+(y*width))*4)+band); }
Sets the sample for a specific band at the given (x,y) location.
Params:
  • x – the x location
  • y – the y location
  • band – the band to set (must be 1, 2, 3, or 4)
  • sample – the sample value to set
/** * Sets the sample for a specific band at the given (x,y) location. * * @param x the x location * @param y the y location * @param band the band to set (must be 1, 2, 3, or 4) * @param sample the sample value to set */
public void setSample(int x, int y, int band, float sample) { buf.put(((x+(y*width))*4)+band, sample); cacheValid = false; }
Sets the sample for the first band at the given (x,y) location.
Params:
  • x – the x location
  • y – the y location
  • s0 – the sample value to set for the first band
/** * Sets the sample for the first band at the given (x,y) location. * * @param x the x location * @param y the y location * @param s0 the sample value to set for the first band */
public void setSamples(int x, int y, float s0) { int index = (x+(y*width))*4; buf.put(index+0, s0); cacheValid = false; }
Sets the sample for the first two bands at the given (x,y) location.
Params:
  • x – the x location
  • y – the y location
  • s0 – the sample value to set for the first band
  • s1 – the sample value to set for the second band
/** * Sets the sample for the first two bands at the given (x,y) location. * * @param x the x location * @param y the y location * @param s0 the sample value to set for the first band * @param s1 the sample value to set for the second band */
public void setSamples(int x, int y, float s0, float s1) { int index = (x+(y*width))*4; buf.put(index+0, s0); buf.put(index+1, s1); cacheValid = false; }
Sets the sample for the first three bands at the given (x,y) location.
Params:
  • x – the x location
  • y – the y location
  • s0 – the sample value to set for the first band
  • s1 – the sample value to set for the second band
  • s2 – the sample value to set for the third band
/** * Sets the sample for the first three bands at the given (x,y) location. * * @param x the x location * @param y the y location * @param s0 the sample value to set for the first band * @param s1 the sample value to set for the second band * @param s2 the sample value to set for the third band */
public void setSamples(int x, int y, float s0, float s1, float s2) { int index = (x+(y*width))*4; buf.put(index+0, s0); buf.put(index+1, s1); buf.put(index+2, s2); cacheValid = false; }
Sets the sample for each of the four bands at the given (x,y) location.
Params:
  • x – the x location
  • y – the y location
  • s0 – the sample value to set for the first band
  • s1 – the sample value to set for the second band
  • s2 – the sample value to set for the third band
  • s3 – the sample value to set for the fourth band
/** * Sets the sample for each of the four bands at the given (x,y) location. * * @param x the x location * @param y the y location * @param s0 the sample value to set for the first band * @param s1 the sample value to set for the second band * @param s2 the sample value to set for the third band * @param s3 the sample value to set for the fourth band */
public void setSamples(int x, int y, float s0, float s1, float s2, float s3) { int index = (x+(y*width))*4; buf.put(index+0, s0); buf.put(index+1, s1); buf.put(index+2, s2); buf.put(index+3, s3); cacheValid = false; } public void put(float[] floatBuf) { buf.rewind(); buf.put(floatBuf); buf.rewind(); cacheValid = false; } private Map<FilterContext, Entry> cache; public LockableResource getAccelData(FilterContext fctx) { if (cache == null) { cache = new HashMap<FilterContext, Entry>(); } else if (!cacheValid) { for (Entry entry : cache.values()) { entry.valid = false; } cacheValid = true; } // RT-27553 // TODO: ideally this method wouldn't be public in the first place, // but even worse, we're assuming that it is called on the QFT from // HWTwoSamplerPeer.filter()... Renderer renderer = Renderer.getRenderer(fctx); Entry entry = cache.get(fctx); if (entry != null) { entry.texture.lock(); if (entry.texture.isLost()) { entry.texture.unlock(); cache.remove(fctx); entry = null; } } if (entry == null) { LockableResource texture = renderer.createFloatTexture(width, height); entry = new Entry(texture); cache.put(fctx, entry); } if (!entry.valid) { renderer.updateFloatTexture(entry.texture, this); entry.valid = true; } return entry.texture; } private static class Entry { LockableResource texture; boolean valid; Entry(LockableResource texture) { this.texture = texture; } } }