diff options
Diffstat (limited to 'libs/hwui/Gainmap.cpp')
-rw-r--r-- | libs/hwui/Gainmap.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/libs/hwui/Gainmap.cpp b/libs/hwui/Gainmap.cpp index 30f401ef5f01..ea955e25dc2f 100644 --- a/libs/hwui/Gainmap.cpp +++ b/libs/hwui/Gainmap.cpp @@ -15,12 +15,37 @@ */ #include "Gainmap.h" +#include <SkBitmap.h> +#include <SkCanvas.h> +#include <SkColorFilter.h> +#include <SkImagePriv.h> +#include <SkPaint.h> + +#include "HardwareBitmapUploader.h" + namespace android::uirenderer { sp<Gainmap> Gainmap::allocateHardwareGainmap(const sp<Gainmap>& srcGainmap) { auto gainmap = sp<Gainmap>::make(); gainmap->info = srcGainmap->info; - const SkBitmap skSrcBitmap = srcGainmap->bitmap->getSkBitmap(); + SkBitmap skSrcBitmap = srcGainmap->bitmap->getSkBitmap(); + if (skSrcBitmap.info().colorType() == kAlpha_8_SkColorType && + !HardwareBitmapUploader::hasAlpha8Support()) { + // The regular Bitmap::allocateHardwareBitmap will do a conversion that preserves channels, + // so alpha8 maps to the alpha channel of rgba. However, for gainmaps we will interpret + // the data of an rgba buffer differently as we'll only look at the rgb channels + // So we need to map alpha8 to rgbx_8888 essentially + SkBitmap bitmap; + bitmap.allocPixels(skSrcBitmap.info().makeColorType(kN32_SkColorType)); + SkCanvas canvas(bitmap); + SkPaint paint; + const float alphaToOpaque[] = {0, 0, 0, 1, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 255}; + paint.setColorFilter(SkColorFilters::Matrix(alphaToOpaque, SkColorFilters::Clamp::kNo)); + canvas.drawImage(SkMakeImageFromRasterBitmap(skSrcBitmap, kNever_SkCopyPixelsMode), 0, 0, + SkSamplingOptions{}, &paint); + skSrcBitmap = bitmap; + } sk_sp<Bitmap> skBitmap(Bitmap::allocateHardwareBitmap(skSrcBitmap)); if (!skBitmap.get()) { return nullptr; |