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