void ColorMatrixTask::preLaunch()

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