Fix element handling. Add YUV support.
bug 10427951
Change-Id: I2c9cd4faca881e3fa05eb65ab5edaab9f1c6c140
diff --git a/cpp/Element.cpp b/cpp/Element.cpp
index d685595..8223f99 100644
--- a/cpp/Element.cpp
+++ b/cpp/Element.cpp
@@ -73,7 +73,7 @@
#define CREATE_USER(N, T) android::RSC::sp<const Element> Element::N(android::RSC::sp<RS> rs) { \
if (rs->mElements.N == NULL) { \
- rs->mElements.N = (createUser(rs, RS_TYPE_##T)).get(); \
+ rs->mElements.N = (createUser(rs, RS_TYPE_##T)); \
} \
return rs->mElements.N; \
}
@@ -104,22 +104,36 @@
CREATE_USER(MATRIX_2X2, MATRIX_2X2);
#define CREATE_PIXEL(N, T, K) android::RSC::sp<const Element> Element::N(android::RSC::sp<RS> rs) { \
- return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
+ if (rs->mElements.N == NULL) { \
+ rs->mElements.N = createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
+ } \
+ return rs->mElements.N; \
}
+
CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
CREATE_PIXEL(RGB_565, UNSIGNED_5_6_5, PIXEL_RGB);
CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB);
CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
+CREATE_PIXEL(YUV, UNSIGNED_8, PIXEL_YUV);
#define CREATE_VECTOR(N, T) android::RSC::sp<const Element> Element::N##_2(android::RSC::sp<RS> rs) { \
- return createVector(rs, RS_TYPE_##T, 2); \
-} \
+ if (rs->mElements.N##_2 == NULL) { \
+ rs->mElements.N##_2 = createVector(rs, RS_TYPE_##T, 2); \
+ } \
+ return rs->mElements.N##_2; \
+} \
android::RSC::sp<const Element> Element::N##_3(android::RSC::sp<RS> rs) { \
- return createVector(rs, RS_TYPE_##T, 3); \
+ if (rs->mElements.N##_3 == NULL) { \
+ rs->mElements.N##_3 = createVector(rs, RS_TYPE_##T, 3); \
+ } \
+ return rs->mElements.N##_3; \
} \
android::RSC::sp<const Element> Element::N##_4(android::RSC::sp<RS> rs) { \
- return createVector(rs, RS_TYPE_##T, 4); \
+ if (rs->mElements.N##_4 == NULL) { \
+ rs->mElements.N##_4 = createVector(rs, RS_TYPE_##T, 4); \
+ } \
+ return rs->mElements.N##_4; \
}
CREATE_VECTOR(U8, UNSIGNED_8);
CREATE_VECTOR(I8, SIGNED_8);
diff --git a/cpp/ScriptIntrinsics.cpp b/cpp/ScriptIntrinsics.cpp
index e4bf907..2f52896 100644
--- a/cpp/ScriptIntrinsics.cpp
+++ b/cpp/ScriptIntrinsics.cpp
@@ -573,7 +573,7 @@
}
void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) {
- if (!(in->getType()->getElement()->isCompatible(mElement))) {
+ if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) {
mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB");
return;
}
diff --git a/cpp/Type.cpp b/cpp/Type.cpp
index fe80797..bc86a94 100644
--- a/cpp/Type.cpp
+++ b/cpp/Type.cpp
@@ -19,6 +19,12 @@
#include "RenderScript.h"
+// from system/graphics.h
+enum {
+ HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar
+ HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21
+};
+
using namespace android;
using namespace RSC;
@@ -66,6 +72,7 @@
mDimMipmaps = false;
mDimFaces = false;
mElement = NULL;
+ mYuvFormat = RS_YUV_NONE;
}
void Type::updateFromNative() {
@@ -131,6 +138,27 @@
mDimY = value;
}
+void Type::Builder::setZ(uint32_t value) {
+ if(value < 1) {
+ ALOGE("Values of less than 1 for Dimension Z are not valid.");
+ }
+ mDimZ = value;
+}
+
+void Type::Builder::setYuvFormat(RSYuvFormat format) {
+ if (format != RS_YUV_NONE && !(mElement->isCompatible(Element::YUV(mRS)))) {
+ ALOGE("Invalid element for use with YUV.");
+ return;
+ }
+
+ if (format >= RS_YUV_MAX) {
+ ALOGE("Invalid YUV format.");
+ return;
+ }
+ mYuvFormat = format;
+}
+
+
void Type::Builder::setMipmaps(bool value) {
mDimMipmaps = value;
}
@@ -159,6 +187,18 @@
}
}
+ uint32_t nativeYuv;
+ switch(mYuvFormat) {
+ case(RS_YUV_YV12):
+ nativeYuv = HAL_PIXEL_FORMAT_YV12;
+ break;
+ case (RS_YUV_NV21):
+ nativeYuv = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ break;
+ default:
+ nativeYuv = 0;
+ }
+
void * id = RS::dispatch->TypeCreate(mRS->getContext(), mElement->getID(), mDimX, mDimY, mDimZ,
mDimMipmaps, mDimFaces, 0);
Type *t = new Type(id, mRS);
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index 1d0f9de..a2a6fcf 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -53,6 +53,13 @@
};
+ enum RSYuvFormat {
+ RS_YUV_NONE = 0,
+ RS_YUV_YV12 = 1,
+ RS_YUV_NV21 = 2,
+ RS_YUV_MAX = 3
+ };
+
class RS : public android::RSC::LightRefBase<RS> {
public:
@@ -100,15 +107,45 @@
struct {
sp<const Element> U8;
+ sp<const Element> U8_2;
+ sp<const Element> U8_3;
+ sp<const Element> U8_4;
sp<const Element> I8;
+ sp<const Element> I8_2;
+ sp<const Element> I8_3;
+ sp<const Element> I8_4;
sp<const Element> U16;
+ sp<const Element> U16_2;
+ sp<const Element> U16_3;
+ sp<const Element> U16_4;
sp<const Element> I16;
+ sp<const Element> I16_2;
+ sp<const Element> I16_3;
+ sp<const Element> I16_4;
sp<const Element> U32;
+ sp<const Element> U32_2;
+ sp<const Element> U32_3;
+ sp<const Element> U32_4;
sp<const Element> I32;
+ sp<const Element> I32_2;
+ sp<const Element> I32_3;
+ sp<const Element> I32_4;
sp<const Element> U64;
+ sp<const Element> U64_2;
+ sp<const Element> U64_3;
+ sp<const Element> U64_4;
sp<const Element> I64;
+ sp<const Element> I64_2;
+ sp<const Element> I64_3;
+ sp<const Element> I64_4;
sp<const Element> F32;
+ sp<const Element> F32_2;
+ sp<const Element> F32_3;
+ sp<const Element> F32_4;
sp<const Element> F64;
+ sp<const Element> F64_2;
+ sp<const Element> F64_3;
+ sp<const Element> F64_4;
sp<const Element> BOOLEAN;
sp<const Element> ELEMENT;
@@ -129,45 +166,7 @@
sp<const Element> RGBA_4444;
sp<const Element> RGBA_8888;
- sp<const Element> FLOAT_2;
- sp<const Element> FLOAT_3;
- sp<const Element> FLOAT_4;
-
- sp<const Element> DOUBLE_2;
- sp<const Element> DOUBLE_3;
- sp<const Element> DOUBLE_4;
-
- sp<const Element> UCHAR_2;
- sp<const Element> UCHAR_3;
- sp<const Element> UCHAR_4;
-
- sp<const Element> CHAR_2;
- sp<const Element> CHAR_3;
- sp<const Element> CHAR_4;
-
- sp<const Element> USHORT_2;
- sp<const Element> USHORT_3;
- sp<const Element> USHORT_4;
-
- sp<const Element> SHORT_2;
- sp<const Element> SHORT_3;
- sp<const Element> SHORT_4;
-
- sp<const Element> UINT_2;
- sp<const Element> UINT_3;
- sp<const Element> UINT_4;
-
- sp<const Element> INT_2;
- sp<const Element> INT_3;
- sp<const Element> INT_4;
-
- sp<const Element> ULONG_2;
- sp<const Element> ULONG_3;
- sp<const Element> ULONG_4;
-
- sp<const Element> LONG_2;
- sp<const Element> LONG_3;
- sp<const Element> LONG_4;
+ sp<const Element> YUV;
sp<const Element> MATRIX_4X4;
sp<const Element> MATRIX_3X3;
@@ -387,6 +386,7 @@
static sp<const Element> I64_2(sp<RS> rs);
static sp<const Element> I64_3(sp<RS> rs);
static sp<const Element> I64_4(sp<RS> rs);
+ static sp<const Element> YUV(sp<RS> rs);
static sp<const Element> MATRIX_4X4(sp<RS> rs);
static sp<const Element> MATRIX_3X3(sp<RS> rs);
static sp<const Element> MATRIX_2X2(sp<RS> rs);
@@ -539,6 +539,7 @@
uint32_t mDimX;
uint32_t mDimY;
uint32_t mDimZ;
+ RSYuvFormat mYuvFormat;
bool mDimMipmaps;
bool mDimFaces;
size_t mElementCount;
@@ -551,6 +552,10 @@
public:
+ RSYuvFormat getYuvFormat() const {
+ return mYuvFormat;
+ }
+
sp<const Element> getElement() const {
return mElement;
}
@@ -591,6 +596,7 @@
uint32_t mDimX;
uint32_t mDimY;
uint32_t mDimZ;
+ RSYuvFormat mYuvFormat;
bool mDimMipmaps;
bool mDimFaces;
sp<const Element> mElement;
@@ -600,6 +606,8 @@
void setX(uint32_t value);
void setY(uint32_t value);
+ void setZ(uint32_t value);
+ void setYuvFormat(RSYuvFormat format);
void setMipmaps(bool value);
void setFaces(bool value);
sp<const Type> create();