1 /* 2 * Copyright (C) 2012 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 17 #include <malloc.h> 18 #include <string.h> 19 20 #include "RenderScript.h" 21 #include "rsCppInternal.h" 22 23 // from system/graphics.h 24 enum { 25 HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar 26 HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21 27 }; 28 29 using namespace android; 30 using namespace RSC; 31 32 void Type::calcElementCount() { 33 bool hasLod = hasMipmaps(); 34 uint32_t x = getX(); 35 uint32_t y = getY(); 36 uint32_t z = getZ(); 37 uint32_t faces = 1; 38 if (hasFaces()) { 39 faces = 6; 40 } 41 if (x == 0) { 42 x = 1; 43 } 44 if (y == 0) { 45 y = 1; 46 } 47 if (z == 0) { 48 z = 1; 49 } 50 51 uint32_t count = x * y * z * faces; 52 while (hasLod && ((x > 1) || (y > 1) || (z > 1))) { 53 if(x > 1) { 54 x >>= 1; 55 } 56 if(y > 1) { 57 y >>= 1; 58 } 59 if(z > 1) { 60 z >>= 1; 61 } 62 63 count += x * y * z * faces; 64 } 65 mElementCount = count; 66 } 67 68 69 Type::Type(void *id, sp<RS> rs) : BaseObj(id, rs) { 70 mDimX = 0; 71 mDimY = 0; 72 mDimZ = 0; 73 mDimMipmaps = false; 74 mDimFaces = false; 75 mElement = NULL; 76 mYuvFormat = RS_YUV_NONE; 77 } 78 79 void Type::updateFromNative() { 80 // We have 6 integer to obtain mDimX; mDimY; mDimZ; 81 // mDimLOD; mDimFaces; mElement; 82 83 /* 84 int[] dataBuffer = new int[6]; 85 mRS.nTypeGetNativeData(getID(), dataBuffer); 86 87 mDimX = dataBuffer[0]; 88 mDimY = dataBuffer[1]; 89 mDimZ = dataBuffer[2]; 90 mDimMipmaps = dataBuffer[3] == 1 ? true : false; 91 mDimFaces = dataBuffer[4] == 1 ? true : false; 92 93 int elementID = dataBuffer[5]; 94 if(elementID != 0) { 95 mElement = new Element(elementID, mRS); 96 mElement.updateFromNative(); 97 } 98 calcElementCount(); 99 */ 100 } 101 102 sp<const Type> Type::create(sp<RS> rs, sp<const Element> e, uint32_t dimX, uint32_t dimY, uint32_t dimZ) { 103 void * id = RS::dispatch->TypeCreate(rs->getContext(), e->getID(), dimX, dimY, dimZ, false, false, 0); 104 Type *t = new Type(id, rs); 105 106 t->mElement = e; 107 t->mDimX = dimX; 108 t->mDimY = dimY; 109 t->mDimZ = dimZ; 110 t->mDimMipmaps = false; 111 t->mDimFaces = false; 112 113 t->calcElementCount(); 114 115 return t; 116 } 117 118 Type::Builder::Builder(sp<RS> rs, sp<const Element> e) { 119 mRS = rs.get(); 120 mElement = e; 121 mDimX = 0; 122 mDimY = 0; 123 mDimZ = 0; 124 mDimMipmaps = false; 125 mDimFaces = false; 126 } 127 128 void Type::Builder::setX(uint32_t value) { 129 if(value < 1) { 130 ALOGE("Values of less than 1 for Dimension X are not valid."); 131 } 132 mDimX = value; 133 } 134 135 void Type::Builder::setY(uint32_t value) { 136 if(value < 1) { 137 ALOGE("Values of less than 1 for Dimension Y are not valid."); 138 } 139 mDimY = value; 140 } 141 142 void Type::Builder::setZ(uint32_t value) { 143 if(value < 1) { 144 ALOGE("Values of less than 1 for Dimension Z are not valid."); 145 } 146 mDimZ = value; 147 } 148 149 void Type::Builder::setYuvFormat(RSYuvFormat format) { 150 if (format != RS_YUV_NONE && !(mElement->isCompatible(Element::YUV(mRS)))) { 151 ALOGE("Invalid element for use with YUV."); 152 return; 153 } 154 155 if (format >= RS_YUV_MAX) { 156 ALOGE("Invalid YUV format."); 157 return; 158 } 159 mYuvFormat = format; 160 } 161 162 163 void Type::Builder::setMipmaps(bool value) { 164 mDimMipmaps = value; 165 } 166 167 void Type::Builder::setFaces(bool value) { 168 mDimFaces = value; 169 } 170 171 sp<const Type> Type::Builder::create() { 172 if (mDimZ > 0) { 173 if ((mDimX < 1) || (mDimY < 1)) { 174 ALOGE("Both X and Y dimension required when Z is present."); 175 } 176 if (mDimFaces) { 177 ALOGE("Cube maps not supported with 3D types."); 178 } 179 } 180 if (mDimY > 0) { 181 if (mDimX < 1) { 182 ALOGE("X dimension required when Y is present."); 183 } 184 } 185 if (mDimFaces) { 186 if (mDimY < 1) { 187 ALOGE("Cube maps require 2D Types."); 188 } 189 } 190 191 uint32_t nativeYuv; 192 switch(mYuvFormat) { 193 case(RS_YUV_YV12): 194 nativeYuv = HAL_PIXEL_FORMAT_YV12; 195 break; 196 case (RS_YUV_NV21): 197 nativeYuv = HAL_PIXEL_FORMAT_YCrCb_420_SP; 198 break; 199 default: 200 nativeYuv = 0; 201 } 202 203 void * id = RS::dispatch->TypeCreate(mRS->getContext(), mElement->getID(), mDimX, mDimY, mDimZ, 204 mDimMipmaps, mDimFaces, 0); 205 Type *t = new Type(id, mRS); 206 t->mElement = mElement; 207 t->mDimX = mDimX; 208 t->mDimY = mDimY; 209 t->mDimZ = mDimZ; 210 t->mDimMipmaps = mDimMipmaps; 211 t->mDimFaces = mDimFaces; 212 213 t->calcElementCount(); 214 return t; 215 } 216 217