in renderscript-toolkit/src/main/cpp/ColorMatrix.cpp [960:1064]
void ColorMatrixTask::preLaunch(size_t inVectorSize, int inType, size_t outVectorSize,
int outType) {
if (inType == outType) {
if (outType == RS_TYPE_UNSIGNED_8) {
updateCoeffCache(1.f, 255.f);
} else {
updateCoeffCache(1.f, 1.f);
}
} else {
if (outType == RS_TYPE_UNSIGNED_8) {
updateCoeffCache(255.f, 255.f);
} else {
updateCoeffCache(1.f / 255.f, 1.f);
}
}
Key_t key = computeKey(inVectorSize, inType, outVectorSize, outType);
#else
void ColorMatrixTask::preLaunch(size_t inVectorSize, size_t outVectorSize) {
updateCoeffCache(1.f, 255.f);
Key_t key = computeKey(inVectorSize, outVectorSize);
#endif // ANDROID_RENDERSCRIPT_TOOLKIT_SUPPORTS_FLOAT
#if defined(ARCH_X86_HAVE_SSSE3)
if ((mOptKernel == nullptr) || (mLastKey.key != key.key)) {
// FIXME: Disable mOptKernel to pass RS color matrix CTS cases
// mOptKernel =
// (void (*)(void *, const void *, const int16_t *, uint32_t)) selectKernel(key);
mLastKey = key;
}
#else //if !defined(ARCH_X86_HAVE_SSSE3)
if ((mOptKernel == nullptr) || (mLastKey.key != key.key)) {
if (mBuf) munmap(mBuf, mBufSize);
mBuf = nullptr;
mOptKernel = nullptr;
if (build(key)) {
mOptKernel = (void (*)(void *, const void *, const int16_t *, uint32_t)) mBuf;
}
#if defined(ARCH_ARM64_USE_INTRINSICS)
else {
int dt = key.u.outVecSize + (key.u.outType == RS_TYPE_FLOAT_32 ? 4 : 0);
int st = key.u.inVecSize + (key.u.inType == RS_TYPE_FLOAT_32 ? 4 : 0);
uint32_t mm = 0;
int i;
for (i = 0; i < 4; i++)
{
uint32_t m = (key.u.coeffMask >> i) & 0x1111;
m = ((m * 0x249) >> 9) & 15;
m |= ((key.u.addMask >> i) & 1) << 4;
mm |= m << (i * 5);
}
if (key.u.inType == RS_TYPE_FLOAT_32 || key.u.outType == RS_TYPE_FLOAT_32) {
rsdIntrinsicColorMatrixSetup_float_K(&mFnTab, mm, dt, st);
} else {
rsdIntrinsicColorMatrixSetup_int_K(&mFnTab, mm, dt, st);
}
}
#endif
mLastKey = key;
}
#endif //if !defined(ARCH_X86_HAVE_SSSE3)
}
void ColorMatrixTask::processData(int /* threadIndex */, size_t startX, size_t startY, size_t endX,
size_t endY) {
for (size_t y = startY; y < endY; y++) {
size_t offset = mSizeX * y + startX;
uchar* in = ((uchar*)mIn) + offset * paddedSize(mInputVectorSize);
uchar* out = ((uchar*)mOut) + offset * paddedSize(mVectorSize);
kernel(out, in, startX, endX);
}
}
static const float fourZeroes[]{0.0f, 0.0f, 0.0f, 0.0f};
void RenderScriptToolkit::colorMatrix(const void* in, void* out, size_t inputVectorSize,
size_t outputVectorSize, size_t sizeX, size_t sizeY,
const float* matrix, const float* addVector,
const Restriction* restriction) {
#ifdef ANDROID_RENDERSCRIPT_TOOLKIT_VALIDATE
if (!validRestriction(LOG_TAG, sizeX, sizeY, restriction)) {
return;
}
if (inputVectorSize < 1 || inputVectorSize > 4) {
ALOGE("The inputVectorSize should be between 1 and 4. %zu provided.", inputVectorSize);
return;
}
if (outputVectorSize < 1 || outputVectorSize > 4) {
ALOGE("The outputVectorSize should be between 1 and 4. %zu provided.", outputVectorSize);
return;
}
#endif
if (addVector == nullptr) {
addVector = fourZeroes;
}
ColorMatrixTask task(in, out, inputVectorSize, outputVectorSize, sizeX, sizeY, matrix,
addVector, restriction);
processor->doTask(&task);
}
} // namespace renderscript