Shader.java revision 3915e25d41ce40f24fd41d8bcd6a058403d0bbc5
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.graphics; 18 19import android.annotation.NonNull; 20import android.annotation.Nullable; 21 22import libcore.util.NativeAllocationRegistry; 23 24/** 25 * Shader is the based class for objects that return horizontal spans of colors 26 * during drawing. A subclass of Shader is installed in a Paint calling 27 * paint.setShader(shader). After that any object (other than a bitmap) that is 28 * drawn with that paint will get its color(s) from the shader. 29 */ 30public class Shader { 31 32 private static class NoImagePreloadHolder { 33 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( 34 Shader.class.getClassLoader(), nativeGetFinalizer(), 50); 35 } 36 37 /** 38 * @deprecated Use subclass constructors directly instead. 39 */ 40 @Deprecated 41 public Shader() {} 42 43 /** 44 * Current native shader instance. Created and updated lazily when {@link #getNativeInstance()} 45 * is called - otherwise may be out of date with java setters/properties. 46 */ 47 private long mNativeInstance; 48 // Runnable to do immediate destruction 49 private Runnable mCleaner; 50 51 /** 52 * Current matrix - always set to null if local matrix is identity. 53 */ 54 private Matrix mLocalMatrix; 55 56 public enum TileMode { 57 /** 58 * replicate the edge color if the shader draws outside of its 59 * original bounds 60 */ 61 CLAMP (0), 62 /** 63 * repeat the shader's image horizontally and vertically 64 */ 65 REPEAT (1), 66 /** 67 * repeat the shader's image horizontally and vertically, alternating 68 * mirror images so that adjacent images always seam 69 */ 70 MIRROR (2); 71 72 TileMode(int nativeInt) { 73 this.nativeInt = nativeInt; 74 } 75 final int nativeInt; 76 } 77 78 /** 79 * Return true if the shader has a non-identity local matrix. 80 * @param localM Set to the local matrix of the shader, if the shader's matrix is non-null. 81 * @return true if the shader has a non-identity local matrix 82 */ 83 public boolean getLocalMatrix(@NonNull Matrix localM) { 84 if (mLocalMatrix != null) { 85 localM.set(mLocalMatrix); 86 return true; // presence of mLocalMatrix means it's not identity 87 } 88 return false; 89 } 90 91 /** 92 * Set the shader's local matrix. Passing null will reset the shader's 93 * matrix to identity. 94 * 95 * @param localM The shader's new local matrix, or null to specify identity 96 */ 97 public void setLocalMatrix(@Nullable Matrix localM) { 98 if (localM == null || localM.isIdentity()) { 99 if (mLocalMatrix != null) { 100 mLocalMatrix = null; 101 discardNativeInstance(); 102 } 103 } else { 104 if (mLocalMatrix == null) { 105 mLocalMatrix = new Matrix(localM); 106 discardNativeInstance(); 107 } else if (!mLocalMatrix.equals(localM)) { 108 mLocalMatrix.set(localM); 109 discardNativeInstance(); 110 } 111 } 112 } 113 114 long createNativeInstance(long nativeMatrix) { 115 return 0; 116 } 117 118 /** @hide */ 119 protected final void discardNativeInstance() { 120 if (mNativeInstance != 0) { 121 mCleaner.run(); 122 mCleaner = null; 123 mNativeInstance = 0; 124 } 125 } 126 127 /** 128 * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently 129 * constructed native instance is no longer valid. 130 * @hide 131 */ 132 protected void verifyNativeInstance() { 133 } 134 135 /** 136 * @hide 137 */ 138 protected Shader copy() { 139 final Shader copy = new Shader(); 140 copyLocalMatrix(copy); 141 return copy; 142 } 143 144 /** 145 * @hide 146 */ 147 protected void copyLocalMatrix(Shader dest) { 148 dest.mLocalMatrix.set(mLocalMatrix); 149 } 150 151 /** 152 * @hide 153 */ 154 public final long getNativeInstance() { 155 // verify mNativeInstance is valid 156 verifyNativeInstance(); 157 158 if (mNativeInstance == 0) { 159 mNativeInstance = createNativeInstance(mLocalMatrix == null 160 ? 0 : mLocalMatrix.native_instance); 161 mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation( 162 this, mNativeInstance); 163 } 164 return mNativeInstance; 165 } 166 167 private static native long nativeGetFinalizer(); 168 169} 170 171