diff options
author | Derek Sollenberger <djsollen@google.com> | 2020-04-08 10:53:46 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2020-04-08 10:53:46 -0400 |
commit | 22d0d4c7f1aadae7d52bf1786655e60ca58eac51 (patch) | |
tree | df53c851d97a2ab1fc7e5e05bd249b90e64d6694 /cmds/bootanimation/BootAnimation.cpp | |
parent | f6408733a17b149b5eb198f7f608d07bb41d1eea (diff) |
Use public APIs for decoding images for the boot animation
HWUI is restricting access to only a set of stable C APIs. Callers like
boot animation are being converted to either the stable C or NDK APIs.
Test: build and verify animation on reboot
Bug: 150782769
Change-Id: I1fb7c9e0ed2f7bcecec109ddc32b1c5a473f7f3a
Diffstat (limited to 'cmds/bootanimation/BootAnimation.cpp')
-rw-r--r-- | cmds/bootanimation/BootAnimation.cpp | 103 |
1 files changed, 63 insertions, 40 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index a1278f358380..f08c79ad6954 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -34,6 +34,7 @@ #include <cutils/atomic.h> #include <cutils/properties.h> +#include <android/imagedecoder.h> #include <androidfw/AssetManager.h> #include <binder/IPCThreadState.h> #include <utils/Errors.h> @@ -51,14 +52,6 @@ #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> -// TODO: Fix Skia. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#include <SkBitmap.h> -#include <SkImage.h> -#include <SkStream.h> -#pragma GCC diagnostic pop - #include <GLES/gl.h> #include <GLES/glext.h> #include <EGL/eglext.h> @@ -165,22 +158,51 @@ void BootAnimation::binderDied(const wp<IBinder>&) requestExit(); } +static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitmapInfo* outInfo) { + AImageDecoder* decoder = nullptr; + AImageDecoder_createFromBuffer(encodedData, dataLength, &decoder); + if (!decoder) { + return nullptr; + } + + const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder); + outInfo->width = AImageDecoderHeaderInfo_getWidth(info); + outInfo->height = AImageDecoderHeaderInfo_getHeight(info); + outInfo->format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(info); + outInfo->stride = AImageDecoder_getMinimumStride(decoder); + outInfo->flags = 0; + + const size_t size = outInfo->stride * outInfo->height; + void* pixels = malloc(size); + int result = AImageDecoder_decodeImage(decoder, pixels, outInfo->stride, size); + AImageDecoder_delete(decoder); + + if (result != ANDROID_IMAGE_DECODER_SUCCESS) { + free(pixels); + return nullptr; + } + return pixels; +} + status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, const char* name) { Asset* asset = assets.open(name, Asset::ACCESS_BUFFER); if (asset == nullptr) return NO_INIT; - SkBitmap bitmap; - sk_sp<SkData> data = SkData::MakeWithoutCopy(asset->getBuffer(false), - asset->getLength()); - sk_sp<SkImage> image = SkImage::MakeFromEncoded(data); - image->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode); + + AndroidBitmapInfo bitmapInfo; + void* pixels = decodeImage(asset->getBuffer(false), asset->getLength(), &bitmapInfo); + auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free }; + asset->close(); delete asset; - const int w = bitmap.width(); - const int h = bitmap.height(); - const void* p = bitmap.getPixels(); + if (!pixels) { + return NO_INIT; + } + + const int w = bitmapInfo.width; + const int h = bitmapInfo.height; GLint crop[4] = { 0, h, w, -h }; texture->w = w; @@ -189,22 +211,22 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, glGenTextures(1, &texture->name); glBindTexture(GL_TEXTURE_2D, texture->name); - switch (bitmap.colorType()) { - case kAlpha_8_SkColorType: + switch (bitmapInfo.format) { + case ANDROID_BITMAP_FORMAT_A_8: glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA, - GL_UNSIGNED_BYTE, p); + GL_UNSIGNED_BYTE, pixels); break; - case kARGB_4444_SkColorType: + case ANDROID_BITMAP_FORMAT_RGBA_4444: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, - GL_UNSIGNED_SHORT_4_4_4_4, p); + GL_UNSIGNED_SHORT_4_4_4_4, pixels); break; - case kN32_SkColorType: + case ANDROID_BITMAP_FORMAT_RGBA_8888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, - GL_UNSIGNED_BYTE, p); + GL_UNSIGNED_BYTE, pixels); break; - case kRGB_565_SkColorType: + case ANDROID_BITMAP_FORMAT_RGB_565: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, - GL_UNSIGNED_SHORT_5_6_5, p); + GL_UNSIGNED_SHORT_5_6_5, pixels); break; default: break; @@ -221,20 +243,21 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) { - SkBitmap bitmap; - sk_sp<SkData> data = SkData::MakeWithoutCopy(map->getDataPtr(), - map->getDataLength()); - sk_sp<SkImage> image = SkImage::MakeFromEncoded(data); - image->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode); + AndroidBitmapInfo bitmapInfo; + void* pixels = decodeImage(map->getDataPtr(), map->getDataLength(), &bitmapInfo); + auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free }; // FileMap memory is never released until application exit. // Release it now as the texture is already loaded and the memory used for // the packed resource can be released. delete map; - const int w = bitmap.width(); - const int h = bitmap.height(); - const void* p = bitmap.getPixels(); + if (!pixels) { + return NO_INIT; + } + + const int w = bitmapInfo.width; + const int h = bitmapInfo.height; GLint crop[4] = { 0, h, w, -h }; int tw = 1 << (31 - __builtin_clz(w)); @@ -242,28 +265,28 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) if (tw < w) tw <<= 1; if (th < h) th <<= 1; - switch (bitmap.colorType()) { - case kN32_SkColorType: + switch (bitmapInfo.format) { + case ANDROID_BITMAP_FORMAT_RGBA_8888: if (!mUseNpotTextures && (tw != w || th != h)) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p); + 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, - GL_UNSIGNED_BYTE, p); + GL_UNSIGNED_BYTE, pixels); } break; - case kRGB_565_SkColorType: + case ANDROID_BITMAP_FORMAT_RGB_565: if (!mUseNpotTextures && (tw != w || th != h)) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr); glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p); + 0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, - GL_UNSIGNED_SHORT_5_6_5, p); + GL_UNSIGNED_SHORT_5_6_5, pixels); } break; default: |