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