Home | History | Annotate | Download | only in cpp
      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;
    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