From 2ded80094ee534cfbf360e89562f9d6f1cee33e0 Mon Sep 17 00:00:00 2001 From: Greg Kaiser Date: Mon, 19 Jul 2021 17:03:27 +0000 Subject: [PATCH] Revert "Migrate boot animation from GLES 1.0 to GLES2.0." This reverts commit d711ac4858337539c2188f47ef015e5b88080830. Reason for revert: Breaks boot animation on wembley device Bug: 194074093 Change-Id: Id6143bfd1e35089a7df88470978cd064de2d839c Test: wembley has boot animation again with this reverted --- cmds/bootanimation/Android.bp | 2 +- cmds/bootanimation/BootAnimation.cpp | 268 +++++++++------------------ cmds/bootanimation/BootAnimation.h | 10 +- 3 files changed, 89 insertions(+), 191 deletions(-) diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp index 3534624a58a23..b2b66c27f795c 100644 --- a/cmds/bootanimation/Android.bp +++ b/cmds/bootanimation/Android.bp @@ -71,7 +71,7 @@ cc_library_shared { "libui", "libjnigraphics", "libEGL", - "libGLESv2", + "libGLESv1_CM", "libgui", ], } diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 25b7f249fc49d..3109c5c1e0753 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -52,8 +52,9 @@ #include #include #include -#include -#include + +#include +#include #include #include "BootAnimation.h" @@ -107,53 +108,6 @@ static const char PROGRESS_PROP_NAME[] = "service.bootanim.progress"; static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays"; static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1; static constexpr size_t TEXT_POS_LEN_MAX = 16; -static const char U_TEXTURE[] = "uTexture"; -static const char U_FADE[] = "uFade"; -static const char U_CROP_AREA[] = "uCropArea"; -static const char A_UV[] = "aUv"; -static const char A_POSITION[] = "aPosition"; -static const char VERTEX_SHADER_SOURCE[] = R"( - attribute vec4 aPosition; - attribute vec2 aUv; - varying vec2 vUv; - void main() { - gl_Position = aPosition; - vUv = aUv; - })"; -static const char IMAGE_FRAG_SHADER_SOURCE[] = R"( - uniform sampler2D uTexture; - uniform float uFade; - varying vec2 vUv; - void main() { - vec4 color = texture2D(uTexture, vUv); - gl_FragColor = vec4(color.x, color.y, color.z, 1.0 - uFade); - })"; -static const char TEXT_FRAG_SHADER_SOURCE[] = R"( - uniform sampler2D uTexture; - uniform vec4 uCropArea; - varying vec2 vUv; - void main() { - vec2 uv = vec2(mix(uCropArea.x, uCropArea.z, vUv.x), - mix(uCropArea.y, uCropArea.w, vUv.y)); - gl_FragColor = texture2D(uTexture, uv); - })"; - -static GLfloat quadPositions[] = { - -0.5f, -0.5f, - +0.5f, -0.5f, - +0.5f, +0.5f, - +0.5f, +0.5f, - -0.5f, +0.5f, - -0.5f, -0.5f -}; -static GLfloat quadUVs[] = { - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 1.0f -}; // --------------------------------------------------------------------------- @@ -255,6 +209,7 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, const int w = bitmapInfo.width; const int h = bitmapInfo.height; + GLint crop[4] = { 0, h, w, -h }; texture->w = w; texture->h = h; @@ -282,10 +237,11 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, break; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); return NO_ERROR; } @@ -307,6 +263,7 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) { const int w = bitmapInfo.width; const int h = bitmapInfo.height; + GLint crop[4] = { 0, h, w, -h }; int tw = 1 << (31 - __builtin_clz(w)); int th = 1 << (31 - __builtin_clz(h)); if (tw < w) tw <<= 1; @@ -340,10 +297,7 @@ status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) { break; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); *width = w; *height = h; @@ -516,9 +470,7 @@ status_t BootAnimation::readyToRun() { eglInitialize(display, nullptr, nullptr); EGLConfig config = getEglConfig(display); EGLSurface surface = eglCreateWindowSurface(display, config, s.get(), nullptr); - // Initialize egl context with client version number 2.0. - EGLint contextAttributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - EGLContext context = eglCreateContext(display, config, nullptr, contextAttributes); + EGLContext context = eglCreateContext(display, config, nullptr, nullptr); EGLint w, h; eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); @@ -551,6 +503,11 @@ status_t BootAnimation::readyToRun() { void BootAnimation::projectSceneToWindow() { glViewport(0, 0, mWidth, mHeight); glScissor(0, 0, mWidth, mHeight); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, static_cast(mWidth), 0, static_cast(mHeight), -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); } void BootAnimation::resizeSurface(int newWidth, int newHeight) { @@ -643,68 +600,8 @@ void BootAnimation::findBootAnimationFile() { } } -GLuint compileShader(GLenum shaderType, const GLchar *source) { - GLuint shader = glCreateShader(shaderType); - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - GLint isCompiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); - if (isCompiled == GL_FALSE) { - SLOGE("Compile shader failed. Shader type: %d", shaderType); - return 0; - } - return shader; -} - -GLuint linkShader(GLuint vertexShader, GLuint fragmentShader) { - GLuint program = glCreateProgram(); - glAttachShader(program, vertexShader); - glAttachShader(program, fragmentShader); - glLinkProgram(program); - GLint isLinked = 0; - glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked); - if (isLinked == GL_FALSE) { - SLOGE("Linking shader failed. Shader handles: vert %d, frag %d", - vertexShader, fragmentShader); - return 0; - } - return program; -} - -void BootAnimation::initShaders() { - GLuint vertexShader = compileShader(GL_VERTEX_SHADER, (const GLchar *)VERTEX_SHADER_SOURCE); - GLuint imageFragmentShader = - compileShader(GL_FRAGMENT_SHADER, (const GLchar *)IMAGE_FRAG_SHADER_SOURCE); - GLuint textFragmentShader = - compileShader(GL_FRAGMENT_SHADER, (const GLchar *)TEXT_FRAG_SHADER_SOURCE); - - // Initialize image shader. - mImageShader = linkShader(vertexShader, imageFragmentShader); - GLint positionLocation = glGetAttribLocation(mImageShader, A_POSITION); - GLint uvLocation = glGetAttribLocation(mImageShader, A_UV); - mImageTextureLocation = glGetUniformLocation(mImageShader, U_TEXTURE); - mImageFadeLocation = glGetUniformLocation(mImageShader, U_FADE); - glEnableVertexAttribArray(positionLocation); - glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, quadPositions); - glVertexAttribPointer(uvLocation, 2, GL_FLOAT, GL_FALSE, 0, quadUVs); - glEnableVertexAttribArray(uvLocation); - - // Initialize text shader. - mTextShader = linkShader(vertexShader, textFragmentShader); - positionLocation = glGetAttribLocation(mTextShader, A_POSITION); - uvLocation = glGetAttribLocation(mTextShader, A_UV); - mTextTextureLocation = glGetUniformLocation(mTextShader, U_TEXTURE); - mTextCropAreaLocation = glGetUniformLocation(mTextShader, U_CROP_AREA); - glEnableVertexAttribArray(positionLocation); - glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, quadPositions); - glVertexAttribPointer(uvLocation, 2, GL_FLOAT, GL_FALSE, 0, quadUVs); - glEnableVertexAttribArray(uvLocation); -} - bool BootAnimation::threadLoop() { bool result; - initShaders(); - // We have no bootanimation file, so we use the stock android logo // animation. if (mZipFileName.isEmpty()) { @@ -726,8 +623,6 @@ bool BootAnimation::threadLoop() { } bool BootAnimation::android() { - glActiveTexture(GL_TEXTURE0); - SLOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot", elapsedRealtime()); initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png"); @@ -736,14 +631,19 @@ bool BootAnimation::android() { mCallbacks->init({}); // clear screen + glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); + glEnable(GL_TEXTURE_2D); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + // Blend state glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const nsecs_t startTime = systemTime(); do { @@ -766,12 +666,12 @@ bool BootAnimation::android() { glEnable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[1].name); - drawTexturedQuad(x, yc, mAndroid[1].w, mAndroid[1].h); - drawTexturedQuad(x + mAndroid[1].w, yc, mAndroid[1].w, mAndroid[1].h); + glDrawTexiOES(x, yc, 0, mAndroid[1].w, mAndroid[1].h); + glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[0].name); - drawTexturedQuad(xc, yc, mAndroid[0].w, mAndroid[0].h); + glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h); EGLBoolean res = eglSwapBuffers(mDisplay, mSurface); if (res == EGL_FALSE) @@ -898,10 +798,10 @@ status_t BootAnimation::initFont(Font* font, const char* fallback) { status = initTexture(font->map, &font->texture.w, &font->texture.h); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } else if (fallback != nullptr) { status = initTexture(&font->texture, mAssets, fallback); } else { @@ -916,11 +816,40 @@ status_t BootAnimation::initFont(Font* font, const char* fallback) { return status; } +void BootAnimation::fadeFrame(const int frameLeft, const int frameBottom, const int frameWidth, + const int frameHeight, const Animation::Part& part, + const int fadedFramesCount) { + glEnable(GL_BLEND); + glEnableClientState(GL_VERTEX_ARRAY); + glDisable(GL_TEXTURE_2D); + // avoid creating a hole due to mixing result alpha with GL_REPLACE texture + glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); + + const float alpha = static_cast(fadedFramesCount) / part.framesToFadeCount; + glColor4f(part.backgroundColor[0], part.backgroundColor[1], part.backgroundColor[2], alpha); + + const float frameStartX = static_cast(frameLeft); + const float frameStartY = static_cast(frameBottom); + const float frameEndX = frameStartX + frameWidth; + const float frameEndY = frameStartY + frameHeight; + const GLfloat frameRect[] = { + frameStartX, frameStartY, + frameEndX, frameStartY, + frameEndX, frameEndY, + frameStartX, frameEndY + }; + glVertexPointer(2, GL_FLOAT, 0, frameRect); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_TEXTURE_2D); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_BLEND); +} + void BootAnimation::drawText(const char* str, const Font& font, bool bold, int* x, int* y) { glEnable(GL_BLEND); // Allow us to draw on top of the animation glBindTexture(GL_TEXTURE_2D, font.texture.name); - glUseProgram(mTextShader); - glUniform1i(mTextTextureLocation, 0); const int len = strlen(str); const int strWidth = font.char_width * len; @@ -936,6 +865,8 @@ void BootAnimation::drawText(const char* str, const Font& font, bool bold, int* *y = mHeight + *y - font.char_height; } + int cropRect[4] = { 0, 0, font.char_width, -font.char_height }; + for (int i = 0; i < len; i++) { char c = str[i]; @@ -947,13 +878,13 @@ void BootAnimation::drawText(const char* str, const Font& font, bool bold, int* const int charPos = (c - FONT_BEGIN_CHAR); // Position in the list of valid characters const int row = charPos / FONT_NUM_COLS; const int col = charPos % FONT_NUM_COLS; - // Bold fonts are expected in the second half of each row. - float v0 = (row + (bold ? 0.5f : 0.0f)) / FONT_NUM_ROWS; - float u0 = ((float)col) / FONT_NUM_COLS; - float v1 = v0 + 1.0f / FONT_NUM_ROWS / 2; - float u1 = u0 + 1.0f / FONT_NUM_COLS; - glUniform4f(mTextCropAreaLocation, u0, v0, u1, v1); - drawTexturedQuad(*x, *y, font.char_width, font.char_height); + cropRect[0] = col * font.char_width; // Left of column + cropRect[1] = row * font.char_height * 2; // Top of row + // Move down to bottom of regular (one char_heigh) or bold (two char_heigh) line + cropRect[1] += bold ? 2 * font.char_height : font.char_height; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); + + glDrawTexiOES(*x, *y, 0, font.char_width, font.char_height); *x += font.char_width; } @@ -1235,16 +1166,19 @@ bool BootAnimation::movie() { // Blend required to draw time on top of animation frames. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); - glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glEnable(GL_TEXTURE_2D); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + bool clockFontInitialized = false; if (mClockEnabled) { clockFontInitialized = @@ -1284,34 +1218,6 @@ bool BootAnimation::shouldStopPlayingPart(const Animation::Part& part, (lastDisplayedProgress == 0 || lastDisplayedProgress == 100); } -// Linear mapping from range to range -float mapLinear(float x, float a1, float a2, float b1, float b2) { - return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); -} - -void BootAnimation::drawTexturedQuad(float xStart, float yStart, float width, float height) { - // Map coordinates from screen space to world space. - float x0 = mapLinear(xStart, 0, mWidth, -1, 1); - float y0 = mapLinear(yStart, 0, mHeight, -1, 1); - float x1 = mapLinear(xStart + width, 0, mWidth, -1, 1); - float y1 = mapLinear(yStart + height, 0, mHeight, -1, 1); - // Update quad vertex positions. - quadPositions[0] = x0; - quadPositions[1] = y0; - quadPositions[2] = x1; - quadPositions[3] = y0; - quadPositions[4] = x1; - quadPositions[5] = y1; - quadPositions[6] = x1; - quadPositions[7] = y1; - quadPositions[8] = x0; - quadPositions[9] = y1; - quadPositions[10] = x0; - quadPositions[11] = y0; - glDrawArrays(GL_TRIANGLES, 0, - sizeof(quadPositions) / sizeof(quadPositions[0]) / 2); -} - bool BootAnimation::playAnimation(const Animation& animation) { const size_t pcount = animation.parts.size(); nsecs_t frameDuration = s2ns(1) / animation.fps; @@ -1324,6 +1230,7 @@ bool BootAnimation::playAnimation(const Animation& animation) { for (size_t i=0 ; i 0) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { - glGenTextures(1, &frame.tid); - glBindTexture(GL_TEXTURE_2D, frame.tid); + if (part.count != 1) { + glGenTextures(1, &frame.tid); + glBindTexture(GL_TEXTURE_2D, frame.tid); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } int w, h; initTexture(frame.map, &w, &h); } @@ -1389,21 +1300,16 @@ bool BootAnimation::playAnimation(const Animation& animation) { // specify the y center as ceiling((mHeight - frame.trimHeight) / 2) // which is equivalent to mHeight - (yc + frame.trimHeight) const int frameDrawY = mHeight - (yc + frame.trimHeight); + glDrawTexiOES(xc, frameDrawY, 0, frame.trimWidth, frame.trimHeight); - float fade = 0; // if the part hasn't been stopped yet then continue fading if necessary if (exitPending() && part.hasFadingPhase()) { - fade = static_cast(++fadedFramesCount) / part.framesToFadeCount; + fadeFrame(xc, frameDrawY, frame.trimWidth, frame.trimHeight, part, + ++fadedFramesCount); if (fadedFramesCount >= part.framesToFadeCount) { fadedFramesCount = MAX_FADED_FRAMES_COUNT; // no more fading } } - glUseProgram(mImageShader); - glUniform1i(mImageTextureLocation, 0); - glUniform1f(mImageFadeLocation, fade); - glEnable(GL_BLEND); - drawTexturedQuad(xc, frameDrawY, frame.trimWidth, frame.trimHeight); - glDisable(GL_BLEND); if (mClockEnabled && mTimeIsAccurate && validClock(part)) { drawClock(animation.clockFont, part.clockPosX, part.clockPosY); diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index 7b616d91c58b7..f8a31c6d87902 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -31,7 +31,7 @@ #include #include -#include +#include namespace android { @@ -166,7 +166,6 @@ private: status_t initTexture(Texture* texture, AssetManager& asset, const char* name); status_t initTexture(FileMap* map, int* width, int* height); status_t initFont(Font* font, const char* fallback); - void initShaders(); bool android(); bool movie(); void drawText(const char* str, const Font& font, bool bold, int* x, int* y); @@ -174,7 +173,6 @@ private: void drawProgress(int percent, const Font& font, const int xPos, const int yPos); void fadeFrame(int frameLeft, int frameBottom, int frameWidth, int frameHeight, const Animation::Part& part, int fadedFramesCount); - void drawTexturedQuad(float xStart, float yStart, float width, float height); bool validClock(const Animation::Part& part); Animation* loadAnimation(const String8&); bool playAnimation(const Animation&); @@ -220,12 +218,6 @@ private: sp mTimeCheckThread = nullptr; sp mCallbacks; Animation* mAnimation = nullptr; - GLuint mImageShader; - GLuint mTextShader; - GLuint mImageFadeLocation; - GLuint mImageTextureLocation; - GLuint mTextCropAreaLocation; - GLuint mTextTextureLocation; }; // ---------------------------------------------------------------------------