Shader.java revision 8a6ad4a89d1b9ed61d3ec6f5bc12d479bc8d9f3b
168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi/* 268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Copyright (C) 2006 The Android Open Source Project 368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * 468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * you may not use this file except in compliance with the License. 668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * You may obtain a copy of the License at 768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * 868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * 1068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * See the License for the specific language governing permissions and 1468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * limitations under the License. 1568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */ 1668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 17de015407a89018f9422254624e1b75703f38defdGlenn Kastenpackage android.graphics; 1868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 1968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Triviimport android.annotation.NonNull; 204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Triviimport android.annotation.Nullable; 214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi 2268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi/** 2368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Shader is the based class for objects that return horizontal spans of colors 2468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * during drawing. A subclass of Shader is installed in a Paint calling 254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi * paint.setShader(shader). After that any object (other than a bitmap) that is 2668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * drawn with that paint will get its color(s) from the shader. 2768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */ 2868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivipublic class Shader { 294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi /** 304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi * @deprecated Use subclass constructors directly instead. 314ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi */ 324ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi @Deprecated 334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi public Shader() {} 344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi 354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi /** 3668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Current native shader instance. Created and updated lazily when {@link #getNativeInstance()} 3737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi * is called - otherwise may be out of date with java setters/properties. 3837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi */ 3949935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten private long mNativeInstance; 4068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 41b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten /** 4268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Current matrix - always set to null if local matrix is identity. 4368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */ 4468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi private Matrix mLocalMatrix; 45b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten 46b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten public enum TileMode { 4768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi /** 48b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten * replicate the edge color if the shader draws outside of its 49b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten * original bounds 50b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten */ 51b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten CLAMP (0), 52b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten /** 53b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten * repeat the shader's image horizontally and vertically 54b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten */ 55b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten REPEAT (1), 56b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten /** 57b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten * repeat the shader's image horizontally and vertically, alternating 58b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten * mirror images so that adjacent images always seam 59b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten */ 60b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten MIRROR (2); 61b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten 62b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten TileMode(int nativeInt) { 63b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten this.nativeInt = nativeInt; 64b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten } 65b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten final int nativeInt; 6668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi } 6768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 6868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi /** 6968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Return true if the shader has a non-identity local matrix. 702f6d462d89356cdaa77299ca27b60c5cca198d98Gloria Wang * @param localM Set to the local matrix of the shader, if the shader's matrix is non-null. 71b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten * @return true if the shader has a non-identity local matrix 72b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten */ 7368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi public boolean getLocalMatrix(@NonNull Matrix localM) { 7437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi if (mLocalMatrix != null) { 7537dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi localM.set(mLocalMatrix); 7649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten return true; // presence of mLocalMatrix means it's not identity 7768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi } 7837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi return false; 7937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi } 8037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi 814ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi /** 824ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi * Set the shader's local matrix. Passing null will reset the shader's 834ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi * matrix to identity. 844ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi * 854ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi * @param localM The shader's new local matrix, or null to specify identity 864ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi */ 874ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi public void setLocalMatrix(@Nullable Matrix localM) { 884ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi if (localM == null || localM.isIdentity()) { 894ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi if (mLocalMatrix != null) { 904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi mLocalMatrix = null; 914ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi discardNativeInstance(); 924ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi } 934ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi } else { 944ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi if (mLocalMatrix == null) { 954ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi mLocalMatrix = new Matrix(localM); 964ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi discardNativeInstance(); 974ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi } else if (!mLocalMatrix.equals(localM)) { 984ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi mLocalMatrix.set(localM); 994ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi discardNativeInstance(); 1004ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi } 10137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi } 10237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi } 10381e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten 10449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten long createNativeInstance(long nativeMatrix) { 10549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten return 0; 10649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten } 10749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten 10881e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten private void discardNativeInstance() { 10981e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten if (mNativeInstance != 0) { 11081e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten nativeSafeUnref(mNativeInstance); 11181e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten mNativeInstance = 0; 11281e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten } 11337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi } 11468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 11581e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten @Override 11668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi protected void finalize() throws Throwable { 11768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi try { 11868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi if (mNativeInstance != 0) { 11949935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten nativeSafeUnref(mNativeInstance); 12049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten } 12149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten mNativeInstance = -1; 12249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten } finally { 12349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten super.finalize(); 12449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten } 12549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten } 12649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten 12749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten /** 12868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * @hide 12949935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten */ 13049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten protected Shader copy() { 13168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi final Shader copy = new Shader(); 13268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi copyLocalMatrix(copy); 13349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten return copy; 13449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten } 13549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten 13668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi /** 13768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * @hide 13868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */ 13968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi protected void copyLocalMatrix(Shader dest) { 14068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi dest.mLocalMatrix.set(mLocalMatrix); 14168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi } 1427ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi 14368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi /** 144ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten * @hide 14568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */ 1465933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten public long getNativeInstance() { 14768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi if (mNativeInstance == -1) { 148e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi throw new IllegalStateException("attempting to use a finalized Shader"); 14968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi } 15068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 15168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi if (mNativeInstance == 0) { 15268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi mNativeInstance = createNativeInstance(mLocalMatrix == null 15368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi ? 0 : mLocalMatrix.native_instance); 15468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi } 15568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi return mNativeInstance; 15637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi } 15768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi 15868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi private static native void nativeSafeUnref(long nativeInstance); 15968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi} 160e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi