Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f1123cb authored by Shan Huang's avatar Shan Huang
Browse files

Revert "Revert "Implement dynamic colors for boot animation.""

This reverts commit 92aa9daa.

Reason for revert: Working on fixing the null pointer dereference that caused the build breakage.

Test: Manual
Bug: 190093578

Change-Id: I30e525bcc9f70f9bcba616aa9b7ad39c5d38b46d
parent 1461e1b1
Loading
Loading
Loading
Loading
+110 −15
Original line number Original line Diff line number Diff line
@@ -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;
@@ -226,6 +252,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;


    // Set decoding option to alpha unpremultiplied so that the R, G, B channels
    // of transparent pixels are preserved.
    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);
@@ -675,9 +705,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 +725,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 +918,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 +1073,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 +1093,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 +1114,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 +1135,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 +1176,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 +1453,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;
@@ -1376,19 +1480,7 @@ bool BootAnimation::playAnimation(const Animation& animation) {


                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));
                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);
                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 +1496,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);
+9 −0
Original line number Original line Diff line number Diff line
@@ -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.
@@ -226,6 +234,7 @@ private:
    GLuint mImageTextureLocation;
    GLuint mImageTextureLocation;
    GLuint mTextCropAreaLocation;
    GLuint mTextCropAreaLocation;
    GLuint mTextTextureLocation;
    GLuint mTextTextureLocation;
    GLuint mImageColorProgressLocation;
};
};


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------