• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = nullptr;
76     mYuvFormat = RS_YUV_NONE;
77 }
78 
updateFromNative()79 void Type::updateFromNative() {
80     BaseObj::updateFromNative();
81 
82     /*
83      * We have 6 integers / pointers (uintptr_t) to obtain from the return buffer:
84      * mDimX     (buffer[0]);
85      * mDimY     (buffer[1]);
86      * mDimZ     (buffer[2]);
87      * mDimLOD   (buffer[3]);
88      * mDimFaces (buffer[4]);
89      * mElement  (buffer[5]);
90      */
91     uintptr_t dataBuffer[6];
92     RS::dispatch->TypeGetNativeData(mRS->getContext(), getID(), dataBuffer, 6);
93 
94     mDimX = (uint32_t)dataBuffer[0];
95     mDimY = (uint32_t)dataBuffer[1];
96     mDimZ = (uint32_t)dataBuffer[2];
97     mDimMipmaps = dataBuffer[3] == 1 ? true : false;
98     mDimFaces = dataBuffer[4] == 1 ? true : false;
99 
100     uintptr_t elementID = dataBuffer[5];
101     if(elementID != 0) {
102         // Just create a new Element and update it from native.
103         sp<Element> e = new Element((void *)elementID, mRS);
104         e->updateFromNative();
105         mElement = e;
106     }
107     calcElementCount();
108 }
109 
create(sp<RS> rs,sp<const Element> e,uint32_t dimX,uint32_t dimY,uint32_t dimZ)110 sp<const Type> Type::create(sp<RS> rs, sp<const Element> e, uint32_t dimX, uint32_t dimY, uint32_t dimZ) {
111     void * id = RS::dispatch->TypeCreate(rs->getContext(), e->getID(), dimX, dimY, dimZ, false, false, 0);
112     Type *t = new Type(id, rs);
113 
114     t->mElement = e;
115     t->mDimX = dimX;
116     t->mDimY = dimY;
117     t->mDimZ = dimZ;
118     t->mDimMipmaps = false;
119     t->mDimFaces = false;
120     t->mYuvFormat = RS_YUV_NONE;
121 
122     t->calcElementCount();
123 
124     return t;
125 }
126 
Builder(sp<RS> rs,sp<const Element> e)127 Type::Builder::Builder(sp<RS> rs, sp<const Element> e) {
128     mRS = rs.get();
129     mElement = e;
130     mDimX = 0;
131     mDimY = 0;
132     mDimZ = 0;
133     mDimMipmaps = false;
134     mDimFaces = false;
135     mYuvFormat = RS_YUV_NONE;
136 }
137 
setX(uint32_t value)138 void Type::Builder::setX(uint32_t value) {
139     if(value < 1) {
140         ALOGE("Values of less than 1 for Dimension X are not valid.");
141     }
142     mDimX = value;
143 }
144 
setY(uint32_t value)145 void Type::Builder::setY(uint32_t value) {
146     if(value < 1) {
147         ALOGE("Values of less than 1 for Dimension Y are not valid.");
148     }
149     mDimY = value;
150 }
151 
setZ(uint32_t value)152 void Type::Builder::setZ(uint32_t value) {
153     if(value < 1) {
154         ALOGE("Values of less than 1 for Dimension Z are not valid.");
155     }
156     mDimZ = value;
157 }
158 
setYuvFormat(RsYuvFormat format)159 void Type::Builder::setYuvFormat(RsYuvFormat format) {
160     if (format != RS_YUV_NONE && !(mElement->isCompatible(Element::YUV(mRS)))) {
161         ALOGE("Invalid element for use with YUV.");
162         return;
163     }
164 
165     if (format != RS_YUV_NONE &&
166         format != RS_YUV_YV12 &&
167         format != RS_YUV_NV21 &&
168         format != RS_YUV_420_888) {
169         ALOGE("Invalid YUV format.");
170         return;
171     }
172     mYuvFormat = format;
173 }
174 
175 
setMipmaps(bool value)176 void Type::Builder::setMipmaps(bool value) {
177     mDimMipmaps = value;
178 }
179 
setFaces(bool value)180 void Type::Builder::setFaces(bool value) {
181     mDimFaces = value;
182 }
183 
create()184 sp<const Type> Type::Builder::create() {
185     if (mDimZ > 0) {
186         if ((mDimX < 1) || (mDimY < 1)) {
187             ALOGE("Both X and Y dimension required when Z is present.");
188             return nullptr;
189         }
190         if (mDimFaces) {
191             ALOGE("Cube maps not supported with 3D types.");
192             return nullptr;
193         }
194     }
195     if (mDimY > 0) {
196         if (mDimX < 1) {
197             ALOGE("X dimension required when Y is present.");
198             return nullptr;
199         }
200     }
201     if (mDimFaces) {
202         if (mDimY < 1) {
203             ALOGE("Cube maps require 2D Types.");
204             return nullptr;
205         }
206     }
207 
208     if (mYuvFormat != RS_YUV_NONE) {
209         if (mDimZ || mDimFaces || mDimMipmaps) {
210             ALOGE("YUV only supports basic 2D.");
211             return nullptr;
212         }
213     }
214 
215     if (mYuvFormat == RS_YUV_420_888) {
216         ALOGE("YUV_420_888 not supported.");
217         return nullptr;
218     }
219 
220     void * id = RS::dispatch->TypeCreate(mRS->getContext(), mElement->getID(), mDimX, mDimY, mDimZ,
221                                          mDimMipmaps, mDimFaces, mYuvFormat);
222     Type *t = new Type(id, mRS);
223     t->mElement = mElement;
224     t->mDimX = mDimX;
225     t->mDimY = mDimY;
226     t->mDimZ = mDimZ;
227     t->mDimMipmaps = mDimMipmaps;
228     t->mDimFaces = mDimFaces;
229     t->mYuvFormat = mYuvFormat;
230 
231     t->calcElementCount();
232     return t;
233 }
234 
235