Merge "Revert "Revert "Revert "Revert "Implement dynamic colors for boot animation.""""" into sc-qpr1-dev am: 813c29b9a5
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15600806 Change-Id: I1bf4b275ef8a195b71e18c2eb19c2979f4c4000f
This commit is contained in:
@@ -107,9 +107,13 @@ static const char PROGRESS_PROP_NAME[] = "service.bootanim.progress";
|
|||||||
static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
|
static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
|
||||||
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
|
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
|
||||||
static constexpr size_t TEXT_POS_LEN_MAX = 16;
|
static constexpr size_t TEXT_POS_LEN_MAX = 16;
|
||||||
|
static const int DYNAMIC_COLOR_COUNT = 4;
|
||||||
static const char U_TEXTURE[] = "uTexture";
|
static const char U_TEXTURE[] = "uTexture";
|
||||||
static const char U_FADE[] = "uFade";
|
static const char U_FADE[] = "uFade";
|
||||||
static const char U_CROP_AREA[] = "uCropArea";
|
static const char U_CROP_AREA[] = "uCropArea";
|
||||||
|
static const char U_START_COLOR_PREFIX[] = "uStartColor";
|
||||||
|
static const char U_END_COLOR_PREFIX[] = "uEndColor";
|
||||||
|
static const char U_COLOR_PROGRESS[] = "uColorProgress";
|
||||||
static const char A_UV[] = "aUv";
|
static const char A_UV[] = "aUv";
|
||||||
static const char A_POSITION[] = "aPosition";
|
static const char A_POSITION[] = "aPosition";
|
||||||
static const char VERTEX_SHADER_SOURCE[] = R"(
|
static const char VERTEX_SHADER_SOURCE[] = R"(
|
||||||
@@ -121,6 +125,28 @@ static const char VERTEX_SHADER_SOURCE[] = R"(
|
|||||||
gl_Position = aPosition;
|
gl_Position = aPosition;
|
||||||
vUv = aUv;
|
vUv = aUv;
|
||||||
})";
|
})";
|
||||||
|
static const char IMAGE_FRAG_DYNAMIC_COLORING_SHADER_SOURCE[] = R"(
|
||||||
|
precision mediump float;
|
||||||
|
uniform sampler2D uTexture;
|
||||||
|
uniform float uFade;
|
||||||
|
uniform float uColorProgress;
|
||||||
|
uniform vec4 uStartColor0;
|
||||||
|
uniform vec4 uStartColor1;
|
||||||
|
uniform vec4 uStartColor2;
|
||||||
|
uniform vec4 uStartColor3;
|
||||||
|
uniform vec4 uEndColor0;
|
||||||
|
uniform vec4 uEndColor1;
|
||||||
|
uniform vec4 uEndColor2;
|
||||||
|
uniform vec4 uEndColor3;
|
||||||
|
varying highp vec2 vUv;
|
||||||
|
void main() {
|
||||||
|
vec4 mask = texture2D(uTexture, vUv);
|
||||||
|
vec4 color = mask.r * mix(uStartColor0, uEndColor0, uColorProgress)
|
||||||
|
+ mask.g * mix(uStartColor1, uEndColor1, uColorProgress)
|
||||||
|
+ mask.b * mix(uStartColor2, uEndColor2, uColorProgress)
|
||||||
|
+ mask.a * mix(uStartColor3, uEndColor3, uColorProgress);
|
||||||
|
gl_FragColor = vec4(color.x, color.y, color.z, (1.0 - uFade)) * color.a;
|
||||||
|
})";
|
||||||
static const char IMAGE_FRAG_SHADER_SOURCE[] = R"(
|
static const char IMAGE_FRAG_SHADER_SOURCE[] = R"(
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
uniform sampler2D uTexture;
|
uniform sampler2D uTexture;
|
||||||
@@ -128,7 +154,7 @@ static const char IMAGE_FRAG_SHADER_SOURCE[] = R"(
|
|||||||
varying highp vec2 vUv;
|
varying highp vec2 vUv;
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = texture2D(uTexture, vUv);
|
vec4 color = texture2D(uTexture, vUv);
|
||||||
gl_FragColor = vec4(color.x, color.y, color.z, 1.0 - uFade);
|
gl_FragColor = vec4(color.x, color.y, color.z, (1.0 - uFade)) * color.a;
|
||||||
})";
|
})";
|
||||||
static const char TEXT_FRAG_SHADER_SOURCE[] = R"(
|
static const char TEXT_FRAG_SHADER_SOURCE[] = R"(
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
@@ -212,7 +238,8 @@ void BootAnimation::binderDied(const wp<IBinder>&) {
|
|||||||
requestExit();
|
requestExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitmapInfo* outInfo) {
|
static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitmapInfo* outInfo,
|
||||||
|
bool premultiplyAlpha) {
|
||||||
AImageDecoder* decoder = nullptr;
|
AImageDecoder* decoder = nullptr;
|
||||||
AImageDecoder_createFromBuffer(encodedData, dataLength, &decoder);
|
AImageDecoder_createFromBuffer(encodedData, dataLength, &decoder);
|
||||||
if (!decoder) {
|
if (!decoder) {
|
||||||
@@ -226,6 +253,10 @@ static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitm
|
|||||||
outInfo->stride = AImageDecoder_getMinimumStride(decoder);
|
outInfo->stride = AImageDecoder_getMinimumStride(decoder);
|
||||||
outInfo->flags = 0;
|
outInfo->flags = 0;
|
||||||
|
|
||||||
|
if (!premultiplyAlpha) {
|
||||||
|
AImageDecoder_setUnpremultipliedRequired(decoder, true);
|
||||||
|
}
|
||||||
|
|
||||||
const size_t size = outInfo->stride * outInfo->height;
|
const size_t size = outInfo->stride * outInfo->height;
|
||||||
void* pixels = malloc(size);
|
void* pixels = malloc(size);
|
||||||
int result = AImageDecoder_decodeImage(decoder, pixels, outInfo->stride, size);
|
int result = AImageDecoder_decodeImage(decoder, pixels, outInfo->stride, size);
|
||||||
@@ -239,13 +270,14 @@ static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitm
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
|
status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
|
||||||
const char* name) {
|
const char* name, bool premultiplyAlpha) {
|
||||||
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
|
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
|
||||||
if (asset == nullptr)
|
if (asset == nullptr)
|
||||||
return NO_INIT;
|
return NO_INIT;
|
||||||
|
|
||||||
AndroidBitmapInfo bitmapInfo;
|
AndroidBitmapInfo bitmapInfo;
|
||||||
void* pixels = decodeImage(asset->getBuffer(false), asset->getLength(), &bitmapInfo);
|
void* pixels = decodeImage(asset->getBuffer(false), asset->getLength(), &bitmapInfo,
|
||||||
|
premultiplyAlpha);
|
||||||
auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };
|
auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };
|
||||||
|
|
||||||
asset->close();
|
asset->close();
|
||||||
@@ -293,9 +325,11 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) {
|
status_t BootAnimation::initTexture(FileMap* map, int* width, int* height,
|
||||||
|
bool premultiplyAlpha) {
|
||||||
AndroidBitmapInfo bitmapInfo;
|
AndroidBitmapInfo bitmapInfo;
|
||||||
void* pixels = decodeImage(map->getDataPtr(), map->getDataLength(), &bitmapInfo);
|
void* pixels = decodeImage(map->getDataPtr(), map->getDataLength(), &bitmapInfo,
|
||||||
|
premultiplyAlpha);
|
||||||
auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };
|
auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };
|
||||||
|
|
||||||
// FileMap memory is never released until application exit.
|
// FileMap memory is never released until application exit.
|
||||||
@@ -675,9 +709,12 @@ GLuint linkShader(GLuint vertexShader, GLuint fragmentShader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BootAnimation::initShaders() {
|
void BootAnimation::initShaders() {
|
||||||
|
bool dynamicColoringEnabled = mAnimation != nullptr && mAnimation->dynamicColoringEnabled;
|
||||||
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, (const GLchar *)VERTEX_SHADER_SOURCE);
|
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, (const GLchar *)VERTEX_SHADER_SOURCE);
|
||||||
GLuint imageFragmentShader =
|
GLuint imageFragmentShader =
|
||||||
compileShader(GL_FRAGMENT_SHADER, (const GLchar *)IMAGE_FRAG_SHADER_SOURCE);
|
compileShader(GL_FRAGMENT_SHADER, dynamicColoringEnabled
|
||||||
|
? (const GLchar *)IMAGE_FRAG_DYNAMIC_COLORING_SHADER_SOURCE
|
||||||
|
: (const GLchar *)IMAGE_FRAG_SHADER_SOURCE);
|
||||||
GLuint textFragmentShader =
|
GLuint textFragmentShader =
|
||||||
compileShader(GL_FRAGMENT_SHADER, (const GLchar *)TEXT_FRAG_SHADER_SOURCE);
|
compileShader(GL_FRAGMENT_SHADER, (const GLchar *)TEXT_FRAG_SHADER_SOURCE);
|
||||||
|
|
||||||
@@ -692,6 +729,22 @@ void BootAnimation::initShaders() {
|
|||||||
glVertexAttribPointer(uvLocation, 2, GL_FLOAT, GL_FALSE, 0, quadUVs);
|
glVertexAttribPointer(uvLocation, 2, GL_FLOAT, GL_FALSE, 0, quadUVs);
|
||||||
glEnableVertexAttribArray(uvLocation);
|
glEnableVertexAttribArray(uvLocation);
|
||||||
|
|
||||||
|
if (dynamicColoringEnabled) {
|
||||||
|
glUseProgram(mImageShader);
|
||||||
|
SLOGI("[BootAnimation] Dynamically coloring boot animation.");
|
||||||
|
for (int i = 0; i < DYNAMIC_COLOR_COUNT; i++) {
|
||||||
|
float *startColor = mAnimation->startColors[i];
|
||||||
|
float *endColor = mAnimation->endColors[i];
|
||||||
|
glUniform4f(glGetUniformLocation(mImageShader,
|
||||||
|
(U_START_COLOR_PREFIX + std::to_string(i)).c_str()),
|
||||||
|
startColor[0], startColor[1], startColor[2], 1 /* alpha */);
|
||||||
|
glUniform4f(glGetUniformLocation(mImageShader,
|
||||||
|
(U_END_COLOR_PREFIX + std::to_string(i)).c_str()),
|
||||||
|
endColor[0], endColor[1], endColor[2], 1 /* alpha */);
|
||||||
|
}
|
||||||
|
mImageColorProgressLocation = glGetUniformLocation(mImageShader, U_COLOR_PROGRESS);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize text shader.
|
// Initialize text shader.
|
||||||
mTextShader = linkShader(vertexShader, textFragmentShader);
|
mTextShader = linkShader(vertexShader, textFragmentShader);
|
||||||
positionLocation = glGetAttribLocation(mTextShader, A_POSITION);
|
positionLocation = glGetAttribLocation(mTextShader, A_POSITION);
|
||||||
@@ -869,6 +922,20 @@ static bool parseColor(const char str[7], float color[3]) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse a color represented as a signed decimal int string.
|
||||||
|
// E.g. "-2757722" (whose hex 2's complement is 0xFFD5EBA6).
|
||||||
|
// If the input color string is empty, set color with values in defaultColor.
|
||||||
|
static void parseColorDecimalString(const std::string& colorString,
|
||||||
|
float color[3], float defaultColor[3]) {
|
||||||
|
if (colorString == "") {
|
||||||
|
memcpy(color, defaultColor, sizeof(float) * 3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int colorInt = atoi(colorString.c_str());
|
||||||
|
color[0] = ((float)((colorInt >> 16) & 0xFF)) / 0xFF; // r
|
||||||
|
color[1] = ((float)((colorInt >> 8) & 0xFF)) / 0xFF; // g
|
||||||
|
color[2] = ((float)(colorInt & 0xFF)) / 0xFF; // b
|
||||||
|
}
|
||||||
|
|
||||||
static bool readFile(ZipFileRO* zip, const char* name, String8& outString) {
|
static bool readFile(ZipFileRO* zip, const char* name, String8& outString) {
|
||||||
ZipEntryRO entry = zip->findEntryByName(name);
|
ZipEntryRO entry = zip->findEntryByName(name);
|
||||||
@@ -1010,6 +1077,8 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char const* s = desString.string();
|
char const* s = desString.string();
|
||||||
|
std::string dynamicColoringPartName = "";
|
||||||
|
bool postDynamicColoring = false;
|
||||||
|
|
||||||
// Parse the description file
|
// Parse the description file
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -1028,7 +1097,13 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
|
|||||||
char color[7] = "000000"; // default to black if unspecified
|
char color[7] = "000000"; // default to black if unspecified
|
||||||
char clockPos1[TEXT_POS_LEN_MAX + 1] = "";
|
char clockPos1[TEXT_POS_LEN_MAX + 1] = "";
|
||||||
char clockPos2[TEXT_POS_LEN_MAX + 1] = "";
|
char clockPos2[TEXT_POS_LEN_MAX + 1] = "";
|
||||||
|
char dynamicColoringPartNameBuffer[ANIM_ENTRY_NAME_MAX];
|
||||||
char pathType;
|
char pathType;
|
||||||
|
// start colors default to black if unspecified
|
||||||
|
char start_color_0[7] = "000000";
|
||||||
|
char start_color_1[7] = "000000";
|
||||||
|
char start_color_2[7] = "000000";
|
||||||
|
char start_color_3[7] = "000000";
|
||||||
|
|
||||||
int nextReadPos;
|
int nextReadPos;
|
||||||
|
|
||||||
@@ -1043,6 +1118,15 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
|
|||||||
} else {
|
} else {
|
||||||
animation.progressEnabled = false;
|
animation.progressEnabled = false;
|
||||||
}
|
}
|
||||||
|
} else if (sscanf(l, "dynamic_colors %" STRTO(ANIM_PATH_MAX) "s #%6s #%6s #%6s #%6s",
|
||||||
|
dynamicColoringPartNameBuffer,
|
||||||
|
start_color_0, start_color_1, start_color_2, start_color_3)) {
|
||||||
|
animation.dynamicColoringEnabled = true;
|
||||||
|
parseColor(start_color_0, animation.startColors[0]);
|
||||||
|
parseColor(start_color_1, animation.startColors[1]);
|
||||||
|
parseColor(start_color_2, animation.startColors[2]);
|
||||||
|
parseColor(start_color_3, animation.startColors[3]);
|
||||||
|
dynamicColoringPartName = std::string(dynamicColoringPartNameBuffer);
|
||||||
} else if (sscanf(l, "%c %d %d %" STRTO(ANIM_PATH_MAX) "s%n",
|
} else if (sscanf(l, "%c %d %d %" STRTO(ANIM_PATH_MAX) "s%n",
|
||||||
&pathType, &count, &pause, path, &nextReadPos) >= 4) {
|
&pathType, &count, &pause, path, &nextReadPos) >= 4) {
|
||||||
if (pathType == 'f') {
|
if (pathType == 'f') {
|
||||||
@@ -1055,6 +1139,16 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
|
|||||||
// "clockPos1=%s, clockPos2=%s",
|
// "clockPos1=%s, clockPos2=%s",
|
||||||
// pathType, count, pause, path, framesToFadeCount, color, clockPos1, clockPos2);
|
// pathType, count, pause, path, framesToFadeCount, color, clockPos1, clockPos2);
|
||||||
Animation::Part part;
|
Animation::Part part;
|
||||||
|
if (path == dynamicColoringPartName) {
|
||||||
|
// Part is specified to use dynamic coloring.
|
||||||
|
part.useDynamicColoring = true;
|
||||||
|
part.postDynamicColoring = false;
|
||||||
|
postDynamicColoring = true;
|
||||||
|
} else {
|
||||||
|
// Part does not use dynamic coloring.
|
||||||
|
part.useDynamicColoring = false;
|
||||||
|
part.postDynamicColoring = postDynamicColoring;
|
||||||
|
}
|
||||||
part.playUntilComplete = pathType == 'c';
|
part.playUntilComplete = pathType == 'c';
|
||||||
part.framesToFadeCount = framesToFadeCount;
|
part.framesToFadeCount = framesToFadeCount;
|
||||||
part.count = count;
|
part.count = count;
|
||||||
@@ -1086,6 +1180,12 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
|
|||||||
s = ++endl;
|
s = ++endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < DYNAMIC_COLOR_COUNT; i++) {
|
||||||
|
parseColorDecimalString(
|
||||||
|
android::base::GetProperty("persist.bootanim.color" + std::to_string(i + 1), ""),
|
||||||
|
animation.endColors[i], animation.startColors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1357,6 +1457,14 @@ bool BootAnimation::playAnimation(const Animation& animation) {
|
|||||||
for (size_t j=0 ; j<fcount ; j++) {
|
for (size_t j=0 ; j<fcount ; j++) {
|
||||||
if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;
|
if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;
|
||||||
|
|
||||||
|
// Color progress is
|
||||||
|
// - the normalized animation progress between [0, 1] for the dynamic coloring part,
|
||||||
|
// - 0 for parts that come before,
|
||||||
|
// - 1 for parts that come after.
|
||||||
|
float colorProgress = part.useDynamicColoring
|
||||||
|
? (float)j / fcount
|
||||||
|
: (part.postDynamicColoring ? 1 : 0);
|
||||||
|
|
||||||
processDisplayEvents();
|
processDisplayEvents();
|
||||||
|
|
||||||
const int animationX = (mWidth - animation.width) / 2;
|
const int animationX = (mWidth - animation.width) / 2;
|
||||||
@@ -1371,24 +1479,14 @@ bool BootAnimation::playAnimation(const Animation& animation) {
|
|||||||
glGenTextures(1, &frame.tid);
|
glGenTextures(1, &frame.tid);
|
||||||
glBindTexture(GL_TEXTURE_2D, frame.tid);
|
glBindTexture(GL_TEXTURE_2D, frame.tid);
|
||||||
int w, h;
|
int w, h;
|
||||||
initTexture(frame.map, &w, &h);
|
// Set decoding option to alpha unpremultiplied so that the R, G, B channels
|
||||||
|
// of transparent pixels are preserved.
|
||||||
|
initTexture(frame.map, &w, &h, false /* don't premultiply alpha */);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int xc = animationX + frame.trimX;
|
const int xc = animationX + frame.trimX;
|
||||||
const int yc = animationY + frame.trimY;
|
const int yc = animationY + frame.trimY;
|
||||||
Region clearReg(Rect(mWidth, mHeight));
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
clearReg.subtractSelf(Rect(xc, yc, xc+frame.trimWidth, yc+frame.trimHeight));
|
|
||||||
if (!clearReg.isEmpty()) {
|
|
||||||
Region::const_iterator head(clearReg.begin());
|
|
||||||
Region::const_iterator tail(clearReg.end());
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
while (head != tail) {
|
|
||||||
const Rect& r2(*head++);
|
|
||||||
glScissor(r2.left, mHeight - r2.bottom, r2.width(), r2.height());
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
}
|
|
||||||
// specify the y center as ceiling((mHeight - frame.trimHeight) / 2)
|
// specify the y center as ceiling((mHeight - frame.trimHeight) / 2)
|
||||||
// which is equivalent to mHeight - (yc + frame.trimHeight)
|
// which is equivalent to mHeight - (yc + frame.trimHeight)
|
||||||
const int frameDrawY = mHeight - (yc + frame.trimHeight);
|
const int frameDrawY = mHeight - (yc + frame.trimHeight);
|
||||||
@@ -1404,6 +1502,9 @@ bool BootAnimation::playAnimation(const Animation& animation) {
|
|||||||
glUseProgram(mImageShader);
|
glUseProgram(mImageShader);
|
||||||
glUniform1i(mImageTextureLocation, 0);
|
glUniform1i(mImageTextureLocation, 0);
|
||||||
glUniform1f(mImageFadeLocation, fade);
|
glUniform1f(mImageFadeLocation, fade);
|
||||||
|
if (animation.dynamicColoringEnabled) {
|
||||||
|
glUniform1f(mImageColorProgressLocation, colorProgress);
|
||||||
|
}
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
drawTexturedQuad(xc, frameDrawY, frame.trimWidth, frame.trimHeight);
|
drawTexturedQuad(xc, frameDrawY, frame.trimWidth, frame.trimHeight);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Font {
|
struct Font {
|
||||||
FileMap* map;
|
FileMap* map = nullptr;
|
||||||
Texture texture;
|
Texture texture;
|
||||||
int char_width;
|
int char_width;
|
||||||
int char_height;
|
int char_height;
|
||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
struct Animation {
|
struct Animation {
|
||||||
struct Frame {
|
struct Frame {
|
||||||
String8 name;
|
String8 name;
|
||||||
FileMap* map;
|
FileMap* map = nullptr;
|
||||||
int trimX;
|
int trimX;
|
||||||
int trimY;
|
int trimY;
|
||||||
int trimWidth;
|
int trimWidth;
|
||||||
@@ -90,6 +90,10 @@ public:
|
|||||||
uint8_t* audioData;
|
uint8_t* audioData;
|
||||||
int audioLength;
|
int audioLength;
|
||||||
Animation* animation;
|
Animation* animation;
|
||||||
|
// Controls if dynamic coloring is enabled for this part.
|
||||||
|
bool useDynamicColoring = false;
|
||||||
|
// Defines if this part is played after the dynamic coloring part.
|
||||||
|
bool postDynamicColoring = false;
|
||||||
|
|
||||||
bool hasFadingPhase() const {
|
bool hasFadingPhase() const {
|
||||||
return !playUntilComplete && framesToFadeCount > 0;
|
return !playUntilComplete && framesToFadeCount > 0;
|
||||||
@@ -105,6 +109,10 @@ public:
|
|||||||
ZipFileRO* zip;
|
ZipFileRO* zip;
|
||||||
Font clockFont;
|
Font clockFont;
|
||||||
Font progressFont;
|
Font progressFont;
|
||||||
|
// Controls if dynamic coloring is enabled for the whole animation.
|
||||||
|
bool dynamicColoringEnabled = false;
|
||||||
|
float startColors[4][3]; // Start colors of dynamic color transition.
|
||||||
|
float endColors[4][3]; // End colors of dynamic color transition.
|
||||||
};
|
};
|
||||||
|
|
||||||
// All callbacks will be called from this class's internal thread.
|
// All callbacks will be called from this class's internal thread.
|
||||||
@@ -163,8 +171,10 @@ private:
|
|||||||
int displayEventCallback(int fd, int events, void* data);
|
int displayEventCallback(int fd, int events, void* data);
|
||||||
void processDisplayEvents();
|
void processDisplayEvents();
|
||||||
|
|
||||||
status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
|
status_t initTexture(Texture* texture, AssetManager& asset, const char* name,
|
||||||
status_t initTexture(FileMap* map, int* width, int* height);
|
bool premultiplyAlpha = true);
|
||||||
|
status_t initTexture(FileMap* map, int* width, int* height,
|
||||||
|
bool premultiplyAlpha = true);
|
||||||
status_t initFont(Font* font, const char* fallback);
|
status_t initFont(Font* font, const char* fallback);
|
||||||
void initShaders();
|
void initShaders();
|
||||||
bool android();
|
bool android();
|
||||||
@@ -226,6 +236,7 @@ private:
|
|||||||
GLuint mImageTextureLocation;
|
GLuint mImageTextureLocation;
|
||||||
GLuint mTextCropAreaLocation;
|
GLuint mTextCropAreaLocation;
|
||||||
GLuint mTextTextureLocation;
|
GLuint mTextTextureLocation;
|
||||||
|
GLuint mImageColorProgressLocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user