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
calcElementCount()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
Type(void * id,sp<RS> rs)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
updateFromNative()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
create(sp<RS> rs,sp<const Element> e,uint32_t dimX,uint32_t dimY,uint32_t dimZ)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
Builder(sp<RS> rs,sp<const Element> e)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
setX(uint32_t value)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
setY(uint32_t value)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
setZ(uint32_t value)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
setYuvFormat(RSYuvFormat format)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
setMipmaps(bool value)163 void Type::Builder::setMipmaps(bool value) {
164 mDimMipmaps = value;
165 }
166
setFaces(bool value)167 void Type::Builder::setFaces(bool value) {
168 mDimFaces = value;
169 }
170
create()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