Android 开机画面和wallpaper总结

2023-04-27,,

Android 开机画面wallpaper总结 

1 kernel的开机画面修改

1、图片需求:
图片格式:png
图片大小:1024x600(具体示lcd分辨率而定)。

2、转换图片png图片。

假设logo.png已经在目录"kernel/drivers/video/logo/logo.png"下,在kernel中依次执行一下步骤:

# cd kernel/drivers/video/logo
# pngtopnm logo.png > logo_linux.pnm
# pnmquant 224 logo_linux.pnm > logo_linux_clut224.pnm
# pnmtoplainpnm logo_linux_clut224.pnm > logo_linux_clut224.ppm

3、修改kernel config。
如果想要修改菜单配置,可以在kernel目录下执行make menuconfig;然后
进Device Drivers
进Graphics Support
进Bootop logo
进standard 224-clor Linux logo选择性加入图片

2 Android的开机画面修改

1、图片需求:
图片格式:png
图片大小:1024x600(具体示lcd分辨率而定)。
图片背景:黑色背景(推荐)

2、制作图片。
2.1 part0
将不需要重复播放的动画导成一张张的png图片(所有图片大小必须相同),依次命名为"00001.png","00002.png",...
(如 00001.png、00002.png、...、00074.png)
将整理好的图片放到"part0"目录下
2.2 part1
将不需要重复播放的动画导成一张张的png图片(所有图片大小必须相同),紧接着part0的图片名称继续命名。
(如 00075.png、00076.png)
将整理好的图片放到"part1"目录下

3、编辑"desc.txt"
如下所示:
desc.txt里面的命令格式如下:

1024 600 30
p 1 0 part0
p 0 0 part1

我逐一解释一下:

1024 600意思是说你开机动画在屏幕先以多少的分辨率显示,注意不要超过屏幕的分辨率,否则你的画面就显示不全了。
30 这个数字是代表着每秒播放的帧数,拿这个开机画面来说,part0文件夹里面共76张图片,播放时间就是76/30=2.533333秒播放完毕,当然在手机里面会有一定的延时,尤其是你的图片文件比较大的情况下,手机播快起来比较卡。
以下部分是实现画面重复位置的
p 1(代表着播放一次) 0(空指令)part0 */这句指令就代表这part0文件夹内的图片只按名称顺序播放一次
p 0(重复播放)0 (空指令)part1 */这一句指令代表着part1文件夹内的图片会循环反复播放

还有一种是指令不常用,下面也解释一下:

p 0 10 part1 这里面的那个10代表着播放完part1文件夹内的图片一遍之后稍作停顿,然后再循环播放一遍,再停顿少许,再播放,再停顿稍许·········重复下去
p 1 10 part1 同理,这句代表着播放完part1文件夹内的图片之后稍作停顿然后继续执行吓一条命令。

4、打包
必须在"windows"系统下,将"part0"、"part1"、"desc.txt"一起打包成"bootanimation.zip"。
打包的时候,必须是"zip"格式,而且压缩方式是“存储”。否则,android不能识别到,会出现黑屏!

5、动画测试
5.1 将制作好的"bootanimation.zip"通过adb导入到android进行测试,命令如下。
# adb remount
# adb push bootanimation.zip /system/media/bootanimation.zip
# adb reboot
5.2 若不需要"bootanimation.zip"动画,直接将"bootanimation.zip"从"system/media"中删除即可。

3 android的默认墙纸修改

1、Android默认墙纸的路径:

frameworks/base/core/res/res/drawable/default_wallpaper.jpg

路径根据工程的不同可以稍微有点变化;具体图片的大小,可以参考原图or根据分辨率计算。

2、同步墙纸到“墙纸设置”选项中

下面解释一下将“修改的墙纸”同步到Launcher2的墙纸设置选项中

2.1 找到Laucher2中实际使用的墙纸和对应的配置文件。例如:
墙纸的配置文件路径,
packages/apps/Launcher2/res/values-sw720dp/wallpapers.xml
墙纸的路径:
packages/apps/Launcher2/res/drawable-sw720dp-nodpi/wallpaper_architecture.jpg
packages/apps/Launcher2/res/drawable-sw720dp-nodpi/wallpaper_architecture_small.jpg

2.2 根据已有的图片,来制作实际的图片。

附录一 android的开机动画流程

1、开机动画程序bootanimation
程序目录:frameworks/base/cmds/bootanimation
主要文件:frameworks/base/cmds/bootanimation/BootAnimation.cpp
调用位置: 在init.rc中调用bootanimation

2、bootanimation流程
2.1 显示方式
判断是否存在"/data/local/bootanimation.zip"或"/system/media/bootanimation.zip",
若存在的话,则显示bootanimation.zip中的动画;
若不存在的话,则显示系统默认的android闪动画面。
具体的代码(在BootAnimation.cpp中):
--> readyToRun()中判断bootanimation.zip是否存在
    --> threadLoop()中根据mAndroidAnimation的值,来区分不同的显示方式
        --> 若mAndroidAnimation为true,则显示默认的动画,调用android()
              若mAndroidAnimation为false,则显示bootanimation.zip中的动画,调用movie()

3、程序代码
BootAnimation.cpp如下:

 /*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ #define LOG_TAG "BootAnimation" #include <stdint.h>
#include <sys/types.h>
#include <math.h>
#include <fcntl.h>
#include <utils/misc.h>
#include <signal.h> #include <cutils/properties.h> #include <androidfw/AssetManager.h>
#include <binder/IPCThreadState.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/threads.h> #include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/DisplayInfo.h>
#include <ui/FramebufferNativeWindow.h> #include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h> #include <core/SkBitmap.h>
#include <core/SkStream.h>
#include <images/SkImageDecoder.h>
#include <media/mediaplayer.h> #include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/eglext.h> #include "BootAnimation.h" #define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
#define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
#define USER_SHUTDOWN_BOOTANIMATION_FILE "/data/local/shutdownanimation.zip"
#define SYSTEM_SHUTDOWN_BOOTANIMATION_FILE "/system/media/shutdownanimation.zip"
#define EXIT_PROP_NAME "service.bootanim.exit"
#define BOOTMUSIC_FILE "/system/media/audio/boot.ogg" //add by cjf
#define BOOTANIMATION_VIDEO "/system/media/bootanimation.mp4" #define FIXED_ONE 1 extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
const struct timespec *request,
struct timespec *remain); namespace android { // --------------------------------------------------------------------------- BootAnimation::BootAnimation() : Thread(false)
{
mSession = new SurfaceComposerClient();
mHardwareRotation = 0;
mFakeRotation = false;
mShutdown = false;
char property[PROPERTY_VALUE_MAX];
if (property_get("ro.sf.hwrotation", property, "0") > 0) {
mHardwareRotation = atoi(property);
} if (property_get("ro.sf.fakerotation", property, "false") > 0) {
mFakeRotation = !strcmp(property, "true");
}
mReverseAxis = mFakeRotation;
} BootAnimation::~BootAnimation() {
} void BootAnimation::isShutdown(bool shutdown) {
mShutdown = shutdown;
} void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);
ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err == NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);
}
} sp<SurfaceComposerClient> BootAnimation::session() const {
return mSession;
} void BootAnimation::binderDied(const wp<IBinder>& who)
{
// woah, surfaceflinger died!
ALOGD("SurfaceFlinger died, exiting..."); // calling requestExit() is not enough here because the Surface code
// might be blocked on a condition variable that will never be updated.
kill( getpid(), SIGKILL );
requestExit();
} status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
const char* name) {
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
if (!asset)
return NO_INIT;
SkBitmap bitmap;
SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
&bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
asset->close();
delete asset; // ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels(); const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels(); GLint crop[4] = { 0, h, w, -h };
texture->w = w;
texture->h = h; glGenTextures(1, &texture->name);
glBindTexture(GL_TEXTURE_2D, texture->name); switch (bitmap.getConfig()) {
case SkBitmap::kA8_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
GL_UNSIGNED_BYTE, p);
break;
case SkBitmap::kARGB_4444_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4, p);
break;
case SkBitmap::kARGB_8888_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
break;
case SkBitmap::kRGB_565_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
break;
default:
break;
} 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;
} status_t BootAnimation::initTexture(void* buffer, size_t len)
{
//StopWatch watch("blah"); SkBitmap bitmap;
SkMemoryStream stream(buffer, len);
SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
codec->setDitherImage(false);
if (codec) {
codec->decode(&stream, &bitmap,
SkBitmap::kARGB_8888_Config,
SkImageDecoder::kDecodePixels_Mode);
delete codec;
} // ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels(); const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels(); 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;
if (th < h) th <<= 1; mBMPWidth = w;
mBMPHeight = h;
mTexWidth = tw;
mTexHeight = th; switch (bitmap.getConfig()) {
case SkBitmap::kARGB_8888_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
}
break; case SkBitmap::kRGB_565_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
}
break;
default:
break;
} glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); return NO_ERROR;
} //add by cjf
status_t BootAnimation::initTexture(SkBitmap bitmap)
{ // ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels(); const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels(); 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;
if (th < h) th <<= 1; mBMPWidth = w;
mBMPHeight = h;
mTexWidth = tw;
mTexHeight = th; switch (bitmap.getConfig()) {
case SkBitmap::kARGB_8888_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
}
break; case SkBitmap::kRGB_565_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
}
break;
default:
break;
} glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); return NO_ERROR;
} status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets(); DisplayInfo dinfo;
status_t status = session()->getDisplayInfo(0, &dinfo);
if (status)
return -1; // create the native surface
sp<SurfaceControl> control = session()->createSurface(
0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction(); sp<Surface> s = control->getSurface();
// initialize opengl and egl
const EGLint attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 0,
EGL_NONE
};
EGLint w, h, dummy;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
surface = eglCreateWindowSurface(display, config, s.get(), NULL);
context = eglCreateContext(display, config, NULL, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
return NO_INIT; mDisplay = display;
mContext = context;
mSurface = surface;
mWidth = w;
mHeight = h;
mFlingerSurfaceControl = control;
mFlingerSurface = s; mAndroidAnimation = true; // If the device has encryption turned on or is in process
// of being encrypted we show the encrypted boot animation.
char decrypt[PROPERTY_VALUE_MAX];
property_get("vold.decrypt", decrypt, ""); bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt); if ((encryptedAnimation &&
(access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) || ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) || ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) {
mAndroidAnimation = false;
}
if (!mShutdown) {
status_t err = mZip.open("/data/local/bootanimation.zip");
if (err != NO_ERROR) {
err = mZip.open("/system/media/bootanimation.zip");
if (err != NO_ERROR) {
mAndroidAnimation = true;
}
} //add by cjf
mMovie = SkMovie::DecodeFile("/system/media/bootanimation.gif");
if (mMovie) {
mGifAnimation = true;
}
if (access(BOOTANIMATION_VIDEO, R_OK) == 0) {
mVideo = true;
} } else {
status_t err = mZip.open("/data/local/shutdownanimation.zip");
if (err != NO_ERROR) {
err = mZip.open("/system/media/shutdownanimation.zip");
if (err != NO_ERROR) {
mAndroidAnimation = true;
}
}
}
return NO_ERROR;
} bool BootAnimation::threadLoop()
{
bool r; //add by cjf
if (mVideo) {
r = video();
} else if (mGifAnimation) {
r = gifMovie();
} else if (mAndroidAnimation) {
r = android();
} else {
r = movie();
} // No need to force exit anymore
property_set(EXIT_PROP_NAME, "0"); eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mFlingerSurface.clear();
mFlingerSurfaceControl.clear();
eglTerminate(mDisplay);
IPCThreadState::self()->stopProcess();
return r;
} void BootAnimation::getTexCoordinate() { GLfloat w_scale = float(mBMPWidth)/mTexWidth;
GLfloat h_scale = float(mBMPHeight)/mTexHeight; if (mFakeRotation) {
mTexCoords[0]=0; mTexCoords[1]=FIXED_ONE*h_scale;
mTexCoords[2]=0; mTexCoords[3]=0;
mTexCoords[4]=FIXED_ONE*w_scale; mTexCoords[5]=0;
mTexCoords[6]=FIXED_ONE*w_scale; mTexCoords[7]=FIXED_ONE*h_scale;
} else {
mTexCoords[0]=0; mTexCoords[1]=0;
mTexCoords[2]=FIXED_ONE*w_scale; mTexCoords[3]=0;
mTexCoords[4]=FIXED_ONE*w_scale; mTexCoords[5]=FIXED_ONE*h_scale;
mTexCoords[6]=0; mTexCoords[7]=FIXED_ONE*h_scale;
}
} void BootAnimation::playMusic()
{
sp<MediaPlayer> mp = new MediaPlayer();
if ((0 == access(BOOTMUSIC_FILE, F_OK)) && mp != NULL) {
mp->setDataSource(BOOTMUSIC_FILE, NULL);
mp->prepare();
mp->start();
}
} bool BootAnimation::android()
{
initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
mBMPWidth = mTexWidth = mBMPHeight = mTexHeight = 1;
getTexCoordinate();
int first = true; // to add startup music
#ifdef BOOTMUSIC_FILE
playMusic();
#endif // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = mWidth / mHeight;
glFrustumf(-ratio, ratio, -1, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrthof(0, mWidth, mHeight, 0, 0, 1); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface); // Blend state
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (mReverseAxis) {
exchangeParameters(&mWidth, &mHeight);
} GLfloat xc = float(mWidth - mAndroid[0].w) / 2;
GLfloat yc = float(mHeight - mAndroid[0].h) / 2; if (mReverseAxis) {
exchangeParameters(&xc, &yc);
exchangeParameters(&mAndroid[0].w, &mAndroid[0].h);
exchangeParameters(&mAndroid[1].w, &mAndroid[1].h);
} const GLfloat mask_vertices[] = {
xc, yc, 0,
xc+mAndroid[0].w, yc, 0,
xc+mAndroid[0].w, yc+mAndroid[0].h, 0,
xc, yc+mAndroid[0].h, 0
}; const GLfloat shine_vertices[] = {
xc, yc, 0,
xc+mAndroid[1].w, yc, 0,
xc+mAndroid[1].w, yc+mAndroid[1].h, 0,
xc, yc+mAndroid[1].h, 0
}; const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
int nelem = sizeof(indices)/sizeof(indices[0]); const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);
glScissor(updateRect.left, updateRect.top, updateRect.width(),
updateRect.height()); const nsecs_t startTime = systemTime();
do {
nsecs_t now = systemTime();
double time = now - startTime;
float t = 0;
GLint x, y, offset; if (mReverseAxis) {
t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].h;
offset = (1 - (t - floorf(t))) * mAndroid[1].h;
y = yc - offset;
} else {
t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;
offset = (1 - (t - floorf(t))) * mAndroid[1].w;
x = xc - offset;
} glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW); glDisable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST); if (mReverseAxis) {
glTranslatef(0, -offset, 0);
} else {
glTranslatef(-offset, 0, 0);
}
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
glVertexPointer(3, GL_FLOAT, 0, shine_vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); if (mReverseAxis) {
glTranslatef(0, mAndroid[1].h, 0);
} else {
glTranslatef(mAndroid[1].w, 0, 0);
}
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); if (mReverseAxis) {
glTranslatef(0, offset - mAndroid[1].h, 0);
} else {
glTranslatef(offset - mAndroid[1].w, 0, 0);
} glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
glVertexPointer(3, GL_FLOAT, 0, mask_vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
if (res == EGL_FALSE)
break; // 12fps: don't animate too fast to preserve CPU
const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
if (sleepTime > 0)
usleep(sleepTime); checkExit();
} while (!exitPending()); glDeleteTextures(1, &mAndroid[0].name);
glDeleteTextures(1, &mAndroid[1].name);
return false;
} void BootAnimation::checkExit() {
// Allow surface flinger to gracefully request shutdown
if(mShutdown)//shutdown animation
{
return;
}
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();
}
} bool BootAnimation::movie()
{
#ifdef BOOTMUSIC_FILE
playMusic();
#endif
ZipFileRO& zip(mZip); size_t numEntries = zip.getNumEntries();
ZipEntryRO desc = zip.findEntryByName("desc.txt");
FileMap* descMap = zip.createEntryFileMap(desc);
ALOGE_IF(!descMap, "descMap is null");
if (!descMap) {
return false;
} String8 desString((char const*)descMap->getDataPtr(),
descMap->getDataLength());
char const* s = desString.string(); Animation animation; // Parse the description file
for (;;) {
const char* endl = strstr(s, "\n");
if (!endl) break;
String8 line(s, endl - s);
const char* l = line.string();
int fps, width, height, count, pause;
char path[256];
char pathType;
if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
//LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
if (mReverseAxis) {
animation.width = height;
animation.height = width;
} else {
animation.width = width;
animation.height = height;
}
animation.fps = fps;
}
else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) {
//LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path);
Animation::Part part;
part.playUntilComplete = pathType == 'c';
part.count = count;
part.pause = pause;
part.path = path;
animation.parts.add(part);
} s = ++endl;
} // read all the data structures
const size_t pcount = animation.parts.size();
for (size_t i=0 ; i<numEntries ; i++) {
char name[256];
ZipEntryRO entry = zip.findEntryByIndex(i);
if (zip.getEntryFileName(entry, name, 256) == 0) {
const String8 entryName(name);
const String8 path(entryName.getPathDir());
const String8 leaf(entryName.getPathLeaf());
if (leaf.size() > 0) {
for (int j=0 ; j<pcount ; j++) {
if (path == animation.parts[j].path) {
int method;
// supports only stored png files
if (zip.getEntryInfo(entry, &method, 0, 0, 0, 0, 0)) {
if (method == ZipFileRO::kCompressStored) {
FileMap* map = zip.createEntryFileMap(entry);
if (map) {
Animation::Frame frame;
frame.name = leaf;
frame.map = map;
Animation::Part& part(animation.parts.editItemAt(j));
part.frames.add(frame);
}
}
}
}
}
}
}
} // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = mWidth / mHeight;
glFrustumf(-ratio, ratio, -1, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrthof(0, mWidth, mHeight, 0, 0, 1); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0);
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); const int xc = (mWidth - animation.width) / 2;
const int yc = ((mHeight - animation.height) / 2);
nsecs_t lastFrame = systemTime();
nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight));
clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); const GLfloat vertices[] = {
xc, yc, 0,
xc+animation.width, yc, 0,
xc+animation.width, yc+animation.height, 0,
xc, yc+animation.height, 0
}; const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
int nelem = sizeof(indices)/sizeof(indices[0]); for (int i=0 ; i<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) {
// Exit any non playuntil complete parts immediately
if(exitPending() && !part.playUntilComplete)
break; for (int j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
const Animation::Frame& frame(part.frames[j]);
nsecs_t lastFrame = systemTime(); if (r > 0) {
glBindTexture(GL_TEXTURE_2D, frame.tid);
} else {
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);
}
initTexture(
frame.map->getDataPtr(),
frame.map->getDataLength()); getTexCoordinate();
} if (!clearReg.isEmpty()) {
Region::const_iterator head(clearReg.begin());
Region::const_iterator tail(clearReg.end());
glEnable(GL_SCISSOR_TEST);
while (head != tail) {
const Rect& r(*head++);
glScissor(r.left, mHeight - r.bottom,
r.width(), r.height());
glClear(GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
} glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime();
nsecs_t delay = frameDuration - (now - lastFrame);
//ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));
lastFrame = now; if (delay > 0) {
struct timespec spec;
spec.tv_sec = (now + delay) / 1000000000;
spec.tv_nsec = (now + delay) % 1000000000;
int err;
do {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
} checkExit();
} usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit
if(exitPending() && !part.count)
break;
} // free the textures for this part
if (part.count != 1) {
for (int j=0 ; j<fcount ; j++) {
const Animation::Frame& frame(part.frames[j]);
glDeleteTextures(1, &frame.tid);
}
}
} return false;
} bool BootAnimation::video()
{
const float MAX_FPS = 60.0f;
const bool LOOP = true;
const float CHECK_DELAY = ns2us(s2ns(1) / MAX_FPS); eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(mDisplay, mSurface); float asp = 1.0f * mWidth / mHeight;
SurfaceComposerClient::openGlobalTransaction();
mFlingerSurfaceControl->setPosition(mWidth, 0);
mFlingerSurfaceControl->setMatrix(0, 1 / asp, -asp, 0);
SurfaceComposerClient::closeGlobalTransaction(); sp<MediaPlayer> mp = new MediaPlayer();
mp->setDataSource(BOOTANIMATION_VIDEO, NULL);
mp->setLooping(true);
mp->setVideoSurfaceTexture(mFlingerSurface->getSurfaceTexture());
mp->prepare();
mp->start();
while(true) {
if(exitPending())
break;
usleep(CHECK_DELAY);
checkExit();
}
mp->stop();
return false;
} //add by cjf
bool BootAnimation::gifMovie()
{
#ifdef BOOTMUSIC_FILE
playMusic();
#endif
GLuint texture = 0;
SkMSec duration = mMovie->duration();
int width = mMovie->width();
int height = mMovie->height(); const float SPEED = 1.0f;
const float MAX_FPS = 60.0f;
const bool LOOP = true;
const SkMSec LOOP_DELAY = 3000; // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = mWidth / mHeight;
glFrustumf(-ratio, ratio, -1, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrthof(0, mWidth, mHeight, 0, 0, 1); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0);
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); if (mReverseAxis) {
exchangeParameters(&width, &height);
} const int xc = (mWidth - width) / 2;
const int yc = ((mHeight - height) / 2);
nsecs_t frameDuration = s2ns(1) / MAX_FPS; Region clearReg(Rect(mWidth, mHeight));
clearReg.subtractSelf(Rect(xc, yc, xc+width, yc+height)); const GLfloat vertices[] = {
xc, yc, 0,
xc+width, yc, 0,
xc+width, yc+height, 0,
xc, yc+height, 0
}; const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
int nelem = sizeof(indices)/sizeof(indices[0]); glBindTexture(GL_TEXTURE_2D, 0); nsecs_t firstFrame = systemTime(); while (true) {
if(exitPending())
break;
nsecs_t lastFrame = systemTime(); SkMSec time = SPEED * (lastFrame - firstFrame) / 1000000; if (LOOP & time >= duration) {
usleep(LOOP_DELAY * 1000);
firstFrame = systemTime();
time = 0;
} mMovie->setTime(time); glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
initTexture(mMovie->bitmap());
getTexCoordinate(); if (!clearReg.isEmpty()) {
Region::const_iterator head(clearReg.begin());
Region::const_iterator tail(clearReg.end());
glEnable(GL_SCISSOR_TEST);
while (head != tail) {
const Rect& r(*head++);
glScissor(r.left, mHeight - r.bottom,
r.width(), r.height());
glClear(GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
} glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime();
nsecs_t delay = frameDuration - (now - lastFrame);
lastFrame = now; if (delay > 0) {
struct timespec spec;
spec.tv_sec = (now + delay) / 1000000000;
spec.tv_nsec = (now + delay) % 1000000000;
int err;
do {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
} checkExit();
glDeleteTextures(1, &texture);
} return false;
} // --------------------------------------------------------------------------- }
; // namespace android

Android 开机画面和wallpaper总结的相关教程结束。

《Android 开机画面和wallpaper总结.doc》

下载本文的Word格式文档,以方便收藏与打印。