in RenderScriptMigrationSample/app/src/main/cpp/ImageProcessor.cpp [123:162]
bool ImageProcessor::configureInputAndOutput(JNIEnv* env, jobject inputBitmap,
int numberOfOutputImages) {
// Create input image from bitmap
mInputImage = Image::createFromBitmap(mContext.get(), env, inputBitmap);
RET_CHECK(mInputImage != nullptr);
LOGV("Input image width = %d, height = %d", mInputImage->width(), mInputImage->height());
// Create intermediate image for blur
mTempImage =
Image::createDeviceLocal(mContext.get(), mInputImage->width(), mInputImage->height(),
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
RET_CHECK(mTempImage != nullptr);
// Create staging output image
mStagingOutputImage =
Image::createDeviceLocal(mContext.get(), mInputImage->width(), mInputImage->height(),
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
RET_CHECK(mStagingOutputImage != nullptr);
// Create output images backed by AHardwareBuffer
RET_CHECK(numberOfOutputImages > 0);
mOutputImages.resize(numberOfOutputImages);
for (int i = 0; i < numberOfOutputImages; i++) {
const AHardwareBuffer_Desc ahwbDesc = {
.width = mInputImage->width(),
.height = mInputImage->height(),
.layers = 1,
.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
};
AHardwareBuffer* buffer = nullptr;
RET_CHECK(AHardwareBuffer_allocate(&ahwbDesc, &buffer) == 0);
mOutputImages[i] = Image::createFromAHardwareBuffer(mContext.get(), buffer);
AHardwareBuffer_release(buffer);
RET_CHECK(mOutputImages[i] != nullptr);
}
return true;
}