Merge "New screen shut down animation." into lmp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b46dea562c
42
core/res/res/raw/color_fade_frag.frag
Normal file
42
core/res/res/raw/color_fade_frag.frag
Normal file
@@ -0,0 +1,42 @@
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
|
||||
precision mediump float;
|
||||
uniform samplerExternalOES texUnit;
|
||||
uniform float opacity;
|
||||
uniform float saturation;
|
||||
uniform float gamma;
|
||||
varying vec2 UV;
|
||||
|
||||
vec3 rgb2hsl(vec3 rgb)
|
||||
{
|
||||
float e = 1.0e-7;
|
||||
|
||||
vec4 p = rgb.g < rgb.b ? vec4(rgb.bg, -1.0, 2.0 / 3.0) : vec4(rgb.gb, 0.0, -1.0 / 3.0);
|
||||
vec4 q = rgb.r < p.x ? vec4(p.xyw, rgb.r) : vec4(rgb.r, p.yzx);
|
||||
|
||||
float v = q.x;
|
||||
float c = v - min(q.w, q.y);
|
||||
float h = abs((q.w - q.y) / (6.0 * c + e) + q.z);
|
||||
float l = v - c * 0.5;
|
||||
float s = c / (1.0 - abs(2.0 * l - 1.0) + e);
|
||||
return clamp(vec3(h, s, l), 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 hsl2rgb(vec3 hsl)
|
||||
{
|
||||
vec3 h = vec3(hsl.x * 6.0);
|
||||
vec3 p = abs(h - vec3(3.0, 2.0, 4.0));
|
||||
vec3 q = 2.0 - p;
|
||||
|
||||
vec3 rgb = clamp(vec3(p.x - 1.0, q.yz), 0.0, 1.0);
|
||||
float c = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;
|
||||
return (rgb - vec3(0.5)) * c + hsl.z;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(texUnit, UV);
|
||||
vec3 hsl = rgb2hsl(color.xyz);
|
||||
vec3 rgb = pow(hsl2rgb(vec3(hsl.x, hsl.y * saturation, hsl.z * opacity)), vec3(gamma));
|
||||
gl_FragColor = vec4(rgb, 1.0);
|
||||
}
|
||||
13
core/res/res/raw/color_fade_vert.vert
Normal file
13
core/res/res/raw/color_fade_vert.vert
Normal file
@@ -0,0 +1,13 @@
|
||||
uniform mat4 proj_matrix;
|
||||
uniform mat4 tex_matrix;
|
||||
uniform float scale;
|
||||
attribute vec2 position;
|
||||
attribute vec2 uv;
|
||||
varying vec2 UV;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 transformed_uv = tex_matrix * vec4(uv.x, uv.y, 1.0, 1.0);
|
||||
UV = transformed_uv.st / transformed_uv.q;
|
||||
gl_Position = vec4(scale, scale, 1.0, 1.0) * (proj_matrix * vec4(position.x, position.y, 0.0, 1.0));
|
||||
}
|
||||
@@ -1266,6 +1266,8 @@
|
||||
<java-symbol type="xml" name="default_zen_mode_config" />
|
||||
<java-symbol type="xml" name="tv_content_rating_systems" />
|
||||
|
||||
<java-symbol type="raw" name="color_fade_vert" />
|
||||
<java-symbol type="raw" name="color_fade_frag" />
|
||||
<java-symbol type="raw" name="accessibility_gestures" />
|
||||
<java-symbol type="raw" name="incognito_mode_start_page" />
|
||||
<java-symbol type="raw" name="loaderror" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
* Copyright (C) 2014 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.
|
||||
@@ -16,11 +16,16 @@
|
||||
|
||||
package com.android.server.display;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
@@ -30,9 +35,8 @@ import android.opengl.EGLConfig;
|
||||
import android.opengl.EGLContext;
|
||||
import android.opengl.EGLDisplay;
|
||||
import android.opengl.EGLSurface;
|
||||
import android.opengl.GLES10;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLES11Ext;
|
||||
import android.os.Looper;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Slog;
|
||||
import android.view.DisplayInfo;
|
||||
@@ -41,10 +45,12 @@ import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
|
||||
import libcore.io.Streams;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.internal.R;
|
||||
|
||||
/**
|
||||
* Bzzzoooop! *crackle*
|
||||
* <p>
|
||||
* Animates a screen transition from on to off or off to on by applying
|
||||
* some GL transformations to a screenshot.
|
||||
@@ -53,20 +59,14 @@ import com.android.server.LocalServices;
|
||||
* that belongs to the {@link DisplayPowerController}.
|
||||
* </p>
|
||||
*/
|
||||
final class ElectronBeam {
|
||||
private static final String TAG = "ElectronBeam";
|
||||
final class ColorFade {
|
||||
private static final String TAG = "ColorFade";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
// The layer for the electron beam surface.
|
||||
// This is currently hardcoded to be one layer above the boot animation.
|
||||
private static final int ELECTRON_BEAM_LAYER = 0x40000001;
|
||||
|
||||
// The relative proportion of the animation to spend performing
|
||||
// the horizontal stretch effect. The remainder is spent performing
|
||||
// the vertical stretch effect.
|
||||
private static final float HSTRETCH_DURATION = 0.5f;
|
||||
private static final float VSTRETCH_DURATION = 1.0f - HSTRETCH_DURATION;
|
||||
private static final int COLOR_FADE_LAYER = 0x40000001;
|
||||
|
||||
// The number of frames to draw when preparing the animation so that it will
|
||||
// be ready to run smoothly. We use 3 frames because we are triple-buffered.
|
||||
@@ -98,6 +98,11 @@ final class ElectronBeam {
|
||||
private final int[] mTexNames = new int[1];
|
||||
private boolean mTexNamesGenerated;
|
||||
private final float mTexMatrix[] = new float[16];
|
||||
private final float mProjMatrix[] = new float[16];
|
||||
private final int[] mGLBuffers = new int[2];
|
||||
private int mTexCoordLoc, mVertexLoc, mTexUnitLoc, mProjMatrixLoc, mTexMatrixLoc;
|
||||
private int mOpacityLoc, mScaleLoc, mGammaLoc, mSaturationLoc;
|
||||
private int mProgram;
|
||||
|
||||
// Vertex and corresponding texture coordinates.
|
||||
// We have 4 2D vertices, so 8 elements. The vertices form a quad.
|
||||
@@ -105,12 +110,12 @@ final class ElectronBeam {
|
||||
private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8);
|
||||
|
||||
/**
|
||||
* Animates an electron beam warming up.
|
||||
* Animates an color fade warming up.
|
||||
*/
|
||||
public static final int MODE_WARM_UP = 0;
|
||||
|
||||
/**
|
||||
* Animates an electron beam shutting off.
|
||||
* Animates an color fade shutting off.
|
||||
*/
|
||||
public static final int MODE_COOL_DOWN = 1;
|
||||
|
||||
@@ -119,19 +124,19 @@ final class ElectronBeam {
|
||||
*/
|
||||
public static final int MODE_FADE = 2;
|
||||
|
||||
public ElectronBeam(int displayId) {
|
||||
public ColorFade(int displayId) {
|
||||
mDisplayId = displayId;
|
||||
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms up the electron beam in preparation for turning on or off.
|
||||
* Warms up the color fade in preparation for turning on or off.
|
||||
* This method prepares a GL context, and captures a screen shot.
|
||||
*
|
||||
* @param mode The desired mode for the upcoming animation.
|
||||
* @return True if the electron beam is ready, false if it is uncontrollable.
|
||||
* @return True if the color fade is ready, false if it is uncontrollable.
|
||||
*/
|
||||
public boolean prepare(int mode) {
|
||||
public boolean prepare(Context context, int mode) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "prepare: mode=" + mode);
|
||||
}
|
||||
@@ -139,18 +144,33 @@ final class ElectronBeam {
|
||||
mMode = mode;
|
||||
|
||||
// Get the display size and layer stack.
|
||||
// This is not expected to change while the electron beam surface is showing.
|
||||
// This is not expected to change while the color fade surface is showing.
|
||||
DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(mDisplayId);
|
||||
mDisplayLayerStack = displayInfo.layerStack;
|
||||
mDisplayWidth = displayInfo.getNaturalWidth();
|
||||
mDisplayHeight = displayInfo.getNaturalHeight();
|
||||
|
||||
// Prepare the surface for drawing.
|
||||
if (!tryPrepare()) {
|
||||
if (!(createSurface() && createEglContext() && createEglSurface() &&
|
||||
captureScreenshotTextureAndSetViewport())) {
|
||||
dismiss();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init GL
|
||||
if (!attachEglContext()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if(!initGLShaders(context) || !initGLBuffers() || checkGlErrors("prepare")) {
|
||||
detachEglContext();
|
||||
dismiss();
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
detachEglContext();
|
||||
}
|
||||
|
||||
// Done.
|
||||
mPrepared = true;
|
||||
|
||||
@@ -169,24 +189,125 @@ final class ElectronBeam {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean tryPrepare() {
|
||||
if (createSurface()) {
|
||||
if (mMode == MODE_FADE) {
|
||||
return true;
|
||||
}
|
||||
return createEglContext()
|
||||
&& createEglSurface()
|
||||
&& captureScreenshotTextureAndSetViewport();
|
||||
private String readFile(Context context, int resourceId) {
|
||||
try{
|
||||
InputStream stream = context.getResources().openRawResource(resourceId);
|
||||
return new String(Streams.readFully(new InputStreamReader(stream)));
|
||||
}
|
||||
return false;
|
||||
catch (IOException e) {
|
||||
Slog.e(TAG, "Unrecognized shader " + Integer.toString(resourceId));
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private int loadShader(Context context, int resourceId, int type) {
|
||||
String source = readFile(context, resourceId);
|
||||
|
||||
int shader = GLES20.glCreateShader(type);
|
||||
|
||||
GLES20.glShaderSource(shader, source);
|
||||
GLES20.glCompileShader(shader);
|
||||
|
||||
int[] compiled = new int[1];
|
||||
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
|
||||
if (compiled[0] == 0) {
|
||||
Slog.e(TAG, "Could not compile shader " + shader + ", " + type + ":");
|
||||
Slog.e(TAG, GLES20.glGetShaderSource(shader));
|
||||
Slog.e(TAG, GLES20.glGetShaderInfoLog(shader));
|
||||
GLES20.glDeleteShader(shader);
|
||||
shader = 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
private boolean initGLShaders(Context context) {
|
||||
int vshader = loadShader(context, com.android.internal.R.raw.color_fade_vert,
|
||||
GLES20.GL_VERTEX_SHADER);
|
||||
int fshader = loadShader(context, com.android.internal.R.raw.color_fade_frag,
|
||||
GLES20.GL_FRAGMENT_SHADER);
|
||||
if (vshader == 0 || fshader == 0) return false;
|
||||
|
||||
mProgram = GLES20.glCreateProgram();
|
||||
|
||||
GLES20.glAttachShader(mProgram, vshader);
|
||||
GLES20.glAttachShader(mProgram, fshader);
|
||||
|
||||
GLES20.glLinkProgram(mProgram);
|
||||
|
||||
mVertexLoc = GLES20.glGetAttribLocation(mProgram, "position");
|
||||
mTexCoordLoc = GLES20.glGetAttribLocation(mProgram, "uv");
|
||||
|
||||
mProjMatrixLoc = GLES20.glGetUniformLocation(mProgram, "proj_matrix");
|
||||
mTexMatrixLoc = GLES20.glGetUniformLocation(mProgram, "tex_matrix");
|
||||
|
||||
mOpacityLoc = GLES20.glGetUniformLocation(mProgram, "opacity");
|
||||
mGammaLoc = GLES20.glGetUniformLocation(mProgram, "gamma");
|
||||
mSaturationLoc = GLES20.glGetUniformLocation(mProgram, "saturation");
|
||||
mScaleLoc = GLES20.glGetUniformLocation(mProgram, "scale");
|
||||
mTexUnitLoc = GLES20.glGetUniformLocation(mProgram, "texUnit");
|
||||
|
||||
GLES20.glUseProgram(mProgram);
|
||||
GLES20.glUniform1i(mTexUnitLoc, 0);
|
||||
GLES20.glUseProgram(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean initGLBuffers() {
|
||||
//Fill vertices
|
||||
setQuad(mVertexBuffer, 0, 0, mDisplayWidth, mDisplayHeight);
|
||||
|
||||
// Setup GL Textures
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
|
||||
GLES20.GL_NEAREST);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
|
||||
GLES20.GL_NEAREST);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
|
||||
GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
|
||||
GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
|
||||
// Setup GL Buffers
|
||||
GLES20.glGenBuffers(2, mGLBuffers, 0);
|
||||
|
||||
// fill vertex buffer
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLBuffers[0]);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, mVertexBuffer.capacity() * 4,
|
||||
mVertexBuffer, GLES20.GL_STATIC_DRAW);
|
||||
|
||||
// fill tex buffer
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLBuffers[1]);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, mTexCoordBuffer.capacity() * 4,
|
||||
mTexCoordBuffer, GLES20.GL_STATIC_DRAW);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h);
|
||||
}
|
||||
vtx.put(0, x);
|
||||
vtx.put(1, y);
|
||||
vtx.put(2, x);
|
||||
vtx.put(3, y + h);
|
||||
vtx.put(4, x + w);
|
||||
vtx.put(5, y + h);
|
||||
vtx.put(6, x + w);
|
||||
vtx.put(7, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the electron beam animation surface and cleans up.
|
||||
* Dismisses the color fade animation surface and cleans up.
|
||||
*
|
||||
* To prevent stray photons from leaking out after the electron beam has been
|
||||
* To prevent stray photons from leaking out after the color fade has been
|
||||
* turned off, it is a good idea to defer dismissing the animation until the
|
||||
* electron beam has been turned back on fully.
|
||||
* color fade has been turned back on fully.
|
||||
*/
|
||||
public void dismiss() {
|
||||
if (DEBUG) {
|
||||
@@ -200,10 +321,10 @@ final class ElectronBeam {
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an animation frame showing the electron beam activated at the
|
||||
* Draws an animation frame showing the color fade activated at the
|
||||
* specified level.
|
||||
*
|
||||
* @param level The electron beam level.
|
||||
* @param level The color fade level.
|
||||
* @return True if successful.
|
||||
*/
|
||||
public boolean draw(float level) {
|
||||
@@ -224,15 +345,18 @@ final class ElectronBeam {
|
||||
}
|
||||
try {
|
||||
// Clear frame to solid black.
|
||||
GLES10.glClearColor(0f, 0f, 0f, 1f);
|
||||
GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT);
|
||||
GLES20.glClearColor(0f, 0f, 0f, 1f);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw the frame.
|
||||
if (level < HSTRETCH_DURATION) {
|
||||
drawHStretch(1.0f - (level / HSTRETCH_DURATION));
|
||||
} else {
|
||||
drawVStretch(1.0f - ((level - HSTRETCH_DURATION) / VSTRETCH_DURATION));
|
||||
}
|
||||
float one_minus_level = 1 - level;
|
||||
float cos = FloatMath.cos((float)Math.PI * one_minus_level);
|
||||
float sign = cos < 0 ? -1 : 1;
|
||||
float opacity = -FloatMath.pow(one_minus_level, 2) + 1;
|
||||
float saturation = FloatMath.pow(level, 4);
|
||||
float scale = (-FloatMath.pow(one_minus_level, 2) + 1) * 0.1f + 0.9f;
|
||||
float gamma = (0.5f * sign * FloatMath.pow(cos, 2) + 0.5f) * 0.9f + 0.1f;
|
||||
drawFaded(opacity, 1.f / gamma, saturation, scale);
|
||||
if (checkGlErrors("drawFrame")) {
|
||||
return false;
|
||||
}
|
||||
@@ -244,139 +368,59 @@ final class ElectronBeam {
|
||||
return showSurface(1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a frame where the content of the electron beam is collapsing inwards upon
|
||||
* itself vertically with red / green / blue channels dispersing and eventually
|
||||
* merging down to a single horizontal line.
|
||||
*
|
||||
* @param stretch The stretch factor. 0.0 is no collapse, 1.0 is full collapse.
|
||||
*/
|
||||
private void drawVStretch(float stretch) {
|
||||
// compute interpolation scale factors for each color channel
|
||||
final float ar = scurve(stretch, 7.5f);
|
||||
final float ag = scurve(stretch, 8.0f);
|
||||
final float ab = scurve(stretch, 8.5f);
|
||||
private void drawFaded(float opacity, float gamma, float saturation, float scale) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "drawVStretch: stretch=" + stretch
|
||||
+ ", ar=" + ar + ", ag=" + ag + ", ab=" + ab);
|
||||
Slog.d(TAG, "drawFaded: opacity=" + opacity + ", gamma=" + gamma +
|
||||
", saturation=" + saturation + ", scale=" + scale);
|
||||
}
|
||||
// Use shaders
|
||||
GLES20.glUseProgram(mProgram);
|
||||
|
||||
// set blending
|
||||
GLES10.glBlendFunc(GLES10.GL_ONE, GLES10.GL_ONE);
|
||||
GLES10.glEnable(GLES10.GL_BLEND);
|
||||
// Set Uniforms
|
||||
GLES20.glUniformMatrix4fv(mProjMatrixLoc, 1, false, mProjMatrix, 0);
|
||||
GLES20.glUniformMatrix4fv(mTexMatrixLoc, 1, false, mTexMatrix, 0);
|
||||
GLES20.glUniform1f(mOpacityLoc, opacity);
|
||||
GLES20.glUniform1f(mGammaLoc, gamma);
|
||||
GLES20.glUniform1f(mSaturationLoc, saturation);
|
||||
GLES20.glUniform1f(mScaleLoc, scale);
|
||||
|
||||
// bind vertex buffer
|
||||
GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer);
|
||||
GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
// Use textures
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]);
|
||||
|
||||
// set-up texturing
|
||||
GLES10.glDisable(GLES10.GL_TEXTURE_2D);
|
||||
GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
||||
// draw the plane
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLBuffers[0]);
|
||||
GLES20.glEnableVertexAttribArray(mVertexLoc);
|
||||
GLES20.glVertexAttribPointer(mVertexLoc, 2, GLES20.GL_FLOAT, false, 0, 0);
|
||||
|
||||
// bind texture and set blending for drawing planes
|
||||
GLES10.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]);
|
||||
GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE,
|
||||
mMode == MODE_WARM_UP ? GLES10.GL_MODULATE : GLES10.GL_REPLACE);
|
||||
GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR);
|
||||
GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR);
|
||||
GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE);
|
||||
GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
|
||||
GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE);
|
||||
GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
||||
GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer);
|
||||
GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLBuffers[1]);
|
||||
GLES20.glEnableVertexAttribArray(mTexCoordLoc);
|
||||
GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, 0);
|
||||
|
||||
// draw the red plane
|
||||
setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ar);
|
||||
GLES10.glColorMask(true, false, false, true);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// draw the green plane
|
||||
setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
|
||||
GLES10.glColorMask(false, true, false, true);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// draw the blue plane
|
||||
setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ab);
|
||||
GLES10.glColorMask(false, false, true, true);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// clean up after drawing planes
|
||||
GLES10.glDisable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
||||
GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY);
|
||||
GLES10.glColorMask(true, true, true, true);
|
||||
|
||||
// draw the white highlight (we use the last vertices)
|
||||
if (mMode == MODE_COOL_DOWN) {
|
||||
GLES10.glColor4f(ag, ag, ag, 1.0f);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// clean up
|
||||
GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
GLES10.glDisable(GLES10.GL_BLEND);
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a frame where the electron beam has been stretched out into
|
||||
* a thin white horizontal line that fades as it collapses inwards.
|
||||
*
|
||||
* @param stretch The stretch factor. 0.0 is maximum stretch / no fade,
|
||||
* 1.0 is collapsed / maximum fade.
|
||||
*/
|
||||
private void drawHStretch(float stretch) {
|
||||
// compute interpolation scale factor
|
||||
final float ag = scurve(stretch, 8.0f);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "drawHStretch: stretch=" + stretch + ", ag=" + ag);
|
||||
}
|
||||
|
||||
if (stretch < 1.0f) {
|
||||
// bind vertex buffer
|
||||
GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer);
|
||||
GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
|
||||
// draw narrow fading white line
|
||||
setHStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
|
||||
GLES10.glColor4f(1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f);
|
||||
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// clean up
|
||||
GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setVStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
|
||||
final float w = dw + (dw * a);
|
||||
final float h = dh - (dh * a);
|
||||
final float x = (dw - w) * 0.5f;
|
||||
final float y = (dh - h) * 0.5f;
|
||||
setQuad(vtx, x, y, w, h);
|
||||
}
|
||||
|
||||
private static void setHStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
|
||||
final float w = 2 * dw * (1.0f - a);
|
||||
final float h = 1.0f;
|
||||
final float x = (dw - w) * 0.5f;
|
||||
final float y = (dh - h) * 0.5f;
|
||||
setQuad(vtx, x, y, w, h);
|
||||
}
|
||||
|
||||
private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h);
|
||||
}
|
||||
vtx.put(0, x);
|
||||
vtx.put(1, y);
|
||||
vtx.put(2, x);
|
||||
vtx.put(3, y + h);
|
||||
vtx.put(4, x + w);
|
||||
vtx.put(5, y + h);
|
||||
vtx.put(6, x + w);
|
||||
vtx.put(7, y);
|
||||
private void ortho(float left, float right, float bottom, float top, float znear, float zfar) {
|
||||
mProjMatrix[0] = 2f / (right - left);
|
||||
mProjMatrix[1] = 0;
|
||||
mProjMatrix[2] = 0;
|
||||
mProjMatrix[3] = 0;
|
||||
mProjMatrix[4] = 0;
|
||||
mProjMatrix[5] = 2f / (top - bottom);
|
||||
mProjMatrix[6] = 0;
|
||||
mProjMatrix[7] = 0;
|
||||
mProjMatrix[8] = 0;
|
||||
mProjMatrix[9] = 0;
|
||||
mProjMatrix[10] = -2f / (zfar - znear);
|
||||
mProjMatrix[11] = 0;
|
||||
mProjMatrix[12] = -(right + left) / (right - left);
|
||||
mProjMatrix[13] = -(top + bottom) / (top - bottom);
|
||||
mProjMatrix[14] = -(zfar + znear) / (zfar - znear);
|
||||
mProjMatrix[15] = 1f;
|
||||
}
|
||||
|
||||
private boolean captureScreenshotTextureAndSetViewport() {
|
||||
@@ -385,7 +429,7 @@ final class ElectronBeam {
|
||||
}
|
||||
try {
|
||||
if (!mTexNamesGenerated) {
|
||||
GLES10.glGenTextures(1, mTexNames, 0);
|
||||
GLES20.glGenTextures(1, mTexNames, 0);
|
||||
if (checkGlErrors("glGenTextures")) {
|
||||
return false;
|
||||
}
|
||||
@@ -413,15 +457,8 @@ final class ElectronBeam {
|
||||
mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f);
|
||||
|
||||
// Set up our viewport.
|
||||
GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
|
||||
GLES10.glMatrixMode(GLES10.GL_PROJECTION);
|
||||
GLES10.glLoadIdentity();
|
||||
GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1);
|
||||
GLES10.glMatrixMode(GLES10.GL_MODELVIEW);
|
||||
GLES10.glLoadIdentity();
|
||||
GLES10.glMatrixMode(GLES10.GL_TEXTURE);
|
||||
GLES10.glLoadIdentity();
|
||||
GLES10.glLoadMatrixf(mTexMatrix, 0);
|
||||
GLES20.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
|
||||
ortho(0, mDisplayWidth, 0, mDisplayHeight, -1, 1);
|
||||
} finally {
|
||||
detachEglContext();
|
||||
}
|
||||
@@ -433,7 +470,7 @@ final class ElectronBeam {
|
||||
mTexNamesGenerated = false;
|
||||
if (attachEglContext()) {
|
||||
try {
|
||||
GLES10.glDeleteTextures(1, mTexNames, 0);
|
||||
GLES20.glDeleteTextures(1, mTexNames, 0);
|
||||
checkGlErrors("glDeleteTextures");
|
||||
} finally {
|
||||
detachEglContext();
|
||||
@@ -460,6 +497,8 @@ final class ElectronBeam {
|
||||
|
||||
if (mEglConfig == null) {
|
||||
int[] eglConfigAttribList = new int[] {
|
||||
EGL14.EGL_RENDERABLE_TYPE,
|
||||
EGL14.EGL_OPENGL_ES2_BIT,
|
||||
EGL14.EGL_RED_SIZE, 8,
|
||||
EGL14.EGL_GREEN_SIZE, 8,
|
||||
EGL14.EGL_BLUE_SIZE, 8,
|
||||
@@ -478,6 +517,7 @@ final class ElectronBeam {
|
||||
|
||||
if (mEglContext == null) {
|
||||
int[] eglContextAttribList = new int[] {
|
||||
EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig,
|
||||
@@ -490,16 +530,6 @@ final class ElectronBeam {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* not used because it is too expensive to create / destroy contexts all of the time
|
||||
private void destroyEglContext() {
|
||||
if (mEglContext != null) {
|
||||
if (!EGL14.eglDestroyContext(mEglDisplay, mEglContext)) {
|
||||
logEglError("eglDestroyContext");
|
||||
}
|
||||
mEglContext = null;
|
||||
}
|
||||
}*/
|
||||
|
||||
private boolean createSurface() {
|
||||
if (mSurfaceSession == null) {
|
||||
mSurfaceSession = new SurfaceSession();
|
||||
@@ -516,7 +546,7 @@ final class ElectronBeam {
|
||||
flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN;
|
||||
}
|
||||
mSurfaceControl = new SurfaceControl(mSurfaceSession,
|
||||
"ElectronBeam", mDisplayWidth, mDisplayHeight,
|
||||
"ColorFade", mDisplayWidth, mDisplayHeight,
|
||||
PixelFormat.OPAQUE, flags);
|
||||
} catch (OutOfResourcesException ex) {
|
||||
Slog.e(TAG, "Unable to create surface.", ex);
|
||||
@@ -584,7 +614,7 @@ final class ElectronBeam {
|
||||
if (!mSurfaceVisible || mSurfaceAlpha != alpha) {
|
||||
SurfaceControl.openTransaction();
|
||||
try {
|
||||
mSurfaceControl.setLayer(ELECTRON_BEAM_LAYER);
|
||||
mSurfaceControl.setLayer(COLOR_FADE_LAYER);
|
||||
mSurfaceControl.setAlpha(alpha);
|
||||
mSurfaceControl.show();
|
||||
} finally {
|
||||
@@ -614,34 +644,6 @@ final class ElectronBeam {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates a value in the range 0 .. 1 along a sigmoid curve
|
||||
* yielding a result in the range 0 .. 1 scaled such that:
|
||||
* scurve(0) == 0, scurve(0.5) == 0.5, scurve(1) == 1.
|
||||
*/
|
||||
private static float scurve(float value, float s) {
|
||||
// A basic sigmoid has the form y = 1.0f / FloatMap.exp(-x * s).
|
||||
// Here we take the input datum and shift it by 0.5 so that the
|
||||
// domain spans the range -0.5 .. 0.5 instead of 0 .. 1.
|
||||
final float x = value - 0.5f;
|
||||
|
||||
// Next apply the sigmoid function to the scaled value
|
||||
// which produces a value in the range 0 .. 1 so we subtract
|
||||
// 0.5 to get a value in the range -0.5 .. 0.5 instead.
|
||||
final float y = sigmoid(x, s) - 0.5f;
|
||||
|
||||
// To obtain the desired boundary conditions we need to scale
|
||||
// the result so that it fills a range of -1 .. 1.
|
||||
final float v = sigmoid(0.5f, s) - 0.5f;
|
||||
|
||||
// And finally remap the value back to a range of 0 .. 1.
|
||||
return y / v * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
private static float sigmoid(float x, float s) {
|
||||
return 1.0f / (1.0f + FloatMath.exp(-x * s));
|
||||
}
|
||||
|
||||
private static FloatBuffer createNativeFloatBuffer(int size) {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(size * 4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
@@ -659,7 +661,7 @@ final class ElectronBeam {
|
||||
private static boolean checkGlErrors(String func, boolean log) {
|
||||
boolean hadError = false;
|
||||
int error;
|
||||
while ((error = GLES10.glGetError()) != GLES10.GL_NO_ERROR) {
|
||||
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
|
||||
if (log) {
|
||||
Slog.e(TAG, func + " failed: error " + error, new Throwable());
|
||||
}
|
||||
@@ -670,7 +672,7 @@ final class ElectronBeam {
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("Electron Beam State:");
|
||||
pw.println("Color Fade State:");
|
||||
pw.println(" mPrepared=" + mPrepared);
|
||||
pw.println(" mMode=" + mMode);
|
||||
pw.println(" mDisplayLayerStack=" + mDisplayLayerStack);
|
||||
@@ -685,7 +687,7 @@ final class ElectronBeam {
|
||||
* Updates the position and transformation of the matrix whenever the display
|
||||
* is rotated. This is a little tricky because the display transaction
|
||||
* callback can be invoked on any thread, not necessarily the thread that
|
||||
* owns the electron beam.
|
||||
* owns the color fade.
|
||||
*/
|
||||
private static final class NaturalSurfaceLayout implements DisplayTransactionListener {
|
||||
private final DisplayManagerInternal mDisplayManagerInternal;
|
||||
@@ -725,7 +727,8 @@ final class ElectronBeam {
|
||||
mSurfaceControl.setMatrix(0, -1, 1, 0);
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
mSurfaceControl.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight);
|
||||
mSurfaceControl.setPosition(displayInfo.logicalWidth,
|
||||
displayInfo.logicalHeight);
|
||||
mSurfaceControl.setMatrix(-1, 0, 0, -1);
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
@@ -64,7 +64,7 @@ import java.io.PrintWriter;
|
||||
* blocker as long as the display is not ready. So most of the work done here
|
||||
* does not need to worry about holding a suspend blocker unless it happens
|
||||
* independently of the display ready signal.
|
||||
*
|
||||
*
|
||||
* For debugging, you can make the electron beam and brightness animations run
|
||||
* slower by changing the "animator duration scale" option in Development Settings.
|
||||
*/
|
||||
@@ -78,14 +78,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
// We might want to turn this off if we cannot get a guarantee that the screen
|
||||
// actually turns on and starts showing new content after the call to set the
|
||||
// screen state returns. Playing the animation can also be somewhat slow.
|
||||
private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false;
|
||||
private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
|
||||
|
||||
|
||||
// The minimum reduction in brightness when dimmed.
|
||||
private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
|
||||
|
||||
private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250;
|
||||
private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400;
|
||||
private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
|
||||
private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 600;
|
||||
|
||||
private static final int MSG_UPDATE_POWER_STATE = 1;
|
||||
private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
|
||||
@@ -107,6 +107,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
// Our handler.
|
||||
private final DisplayControllerHandler mHandler;
|
||||
|
||||
@@ -146,7 +148,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
// True if we should fade the screen while turning it off, false if we should play
|
||||
// a stylish electron beam animation instead.
|
||||
private boolean mElectronBeamFadesConfig;
|
||||
private boolean mColorFadeFadesConfig;
|
||||
|
||||
// The pending power request.
|
||||
// Initially null until the first call to requestPowerState.
|
||||
@@ -223,8 +225,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
private AutomaticBrightnessController mAutomaticBrightnessController;
|
||||
|
||||
// Animators.
|
||||
private ObjectAnimator mElectronBeamOnAnimator;
|
||||
private ObjectAnimator mElectronBeamOffAnimator;
|
||||
private ObjectAnimator mColorFadeOnAnimator;
|
||||
private ObjectAnimator mColorFadeOffAnimator;
|
||||
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
|
||||
|
||||
/**
|
||||
@@ -240,6 +242,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mLights = LocalServices.getService(LightsManager.class);
|
||||
mSensorManager = sensorManager;
|
||||
mBlanker = blanker;
|
||||
mContext = context;
|
||||
|
||||
final Resources resources = context.getResources();
|
||||
|
||||
@@ -287,7 +290,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
|
||||
|
||||
mElectronBeamFadesConfig = resources.getBoolean(
|
||||
mColorFadeFadesConfig = resources.getBoolean(
|
||||
com.android.internal.R.bool.config_animateScreenLights);
|
||||
|
||||
if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
|
||||
@@ -378,17 +381,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
// In the future, we might manage multiple displays independently.
|
||||
mPowerState = new DisplayPowerState(mBlanker,
|
||||
mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),
|
||||
new ElectronBeam(Display.DEFAULT_DISPLAY));
|
||||
new ColorFade(Display.DEFAULT_DISPLAY));
|
||||
|
||||
mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
|
||||
mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f);
|
||||
mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS);
|
||||
mElectronBeamOnAnimator.addListener(mAnimatorListener);
|
||||
mColorFadeOnAnimator = ObjectAnimator.ofFloat(
|
||||
mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
|
||||
mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
|
||||
mColorFadeOnAnimator.addListener(mAnimatorListener);
|
||||
|
||||
mElectronBeamOffAnimator = ObjectAnimator.ofFloat(
|
||||
mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f);
|
||||
mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS);
|
||||
mElectronBeamOffAnimator.addListener(mAnimatorListener);
|
||||
mColorFadeOffAnimator = ObjectAnimator.ofFloat(
|
||||
mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
|
||||
mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
|
||||
mColorFadeOffAnimator.addListener(mAnimatorListener);
|
||||
|
||||
mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
|
||||
mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
|
||||
@@ -600,34 +603,34 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
// Wait for previous off animation to complete beforehand.
|
||||
// It is relatively short but if we cancel it and switch to the
|
||||
// on animation immediately then the results are pretty ugly.
|
||||
if (!mElectronBeamOffAnimator.isStarted()) {
|
||||
if (!mColorFadeOffAnimator.isStarted()) {
|
||||
// Turn the screen on. The contents of the screen may not yet
|
||||
// be visible if the electron beam has not been dismissed because
|
||||
// its last frame of animation is solid black.
|
||||
setScreenState(Display.STATE_ON);
|
||||
if (mPowerRequest.blockScreenOn
|
||||
&& mPowerState.getElectronBeamLevel() == 0.0f) {
|
||||
&& mPowerState.getColorFadeLevel() == 0.0f) {
|
||||
blockScreenOn();
|
||||
} else {
|
||||
unblockScreenOn();
|
||||
if (USE_ELECTRON_BEAM_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
|
||||
if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
|
||||
// Perform screen on animation.
|
||||
if (!mElectronBeamOnAnimator.isStarted()) {
|
||||
if (mPowerState.getElectronBeamLevel() == 1.0f) {
|
||||
mPowerState.dismissElectronBeam();
|
||||
} else if (mPowerState.prepareElectronBeam(
|
||||
mElectronBeamFadesConfig ?
|
||||
ElectronBeam.MODE_FADE :
|
||||
ElectronBeam.MODE_WARM_UP)) {
|
||||
mElectronBeamOnAnimator.start();
|
||||
if (!mColorFadeOnAnimator.isStarted()) {
|
||||
if (mPowerState.getColorFadeLevel() == 1.0f) {
|
||||
mPowerState.dismissColorFade();
|
||||
} else if (mPowerState.prepareColorFade(mContext,
|
||||
mColorFadeFadesConfig ?
|
||||
ColorFade.MODE_FADE :
|
||||
ColorFade.MODE_WARM_UP)) {
|
||||
mColorFadeOnAnimator.start();
|
||||
} else {
|
||||
mElectronBeamOnAnimator.end();
|
||||
mColorFadeOnAnimator.end();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Skip screen on animation.
|
||||
mPowerState.setElectronBeamLevel(1.0f);
|
||||
mPowerState.dismissElectronBeam();
|
||||
mPowerState.setColorFadeLevel(1.0f);
|
||||
mPowerState.dismissColorFade();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -640,8 +643,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|| mPowerState.getScreenState() != Display.STATE_ON) {
|
||||
// Set screen state and dismiss the black surface without fanfare.
|
||||
setScreenState(state);
|
||||
mPowerState.setElectronBeamLevel(1.0f);
|
||||
mPowerState.dismissElectronBeam();
|
||||
mPowerState.setColorFadeLevel(1.0f);
|
||||
mPowerState.dismissColorFade();
|
||||
}
|
||||
} else if (state == Display.STATE_DOZE_SUSPEND) {
|
||||
// Want screen dozing and suspended.
|
||||
@@ -652,27 +655,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|| mPowerState.getScreenState() == Display.STATE_DOZE_SUSPEND) {
|
||||
// Set screen state and dismiss the black surface without fanfare.
|
||||
setScreenState(state);
|
||||
mPowerState.setElectronBeamLevel(1.0f);
|
||||
mPowerState.dismissElectronBeam();
|
||||
mPowerState.setColorFadeLevel(1.0f);
|
||||
mPowerState.dismissColorFade();
|
||||
}
|
||||
} else {
|
||||
// Want screen off.
|
||||
// Wait for previous on animation to complete beforehand.
|
||||
unblockScreenOn();
|
||||
if (!mElectronBeamOnAnimator.isStarted()) {
|
||||
if (!mColorFadeOnAnimator.isStarted()) {
|
||||
if (mPowerRequest.policy == DisplayPowerRequest.POLICY_OFF) {
|
||||
// Perform screen off animation.
|
||||
if (!mElectronBeamOffAnimator.isStarted()) {
|
||||
if (mPowerState.getElectronBeamLevel() == 0.0f) {
|
||||
if (!mColorFadeOffAnimator.isStarted()) {
|
||||
if (mPowerState.getColorFadeLevel() == 0.0f) {
|
||||
setScreenState(Display.STATE_OFF);
|
||||
} else if (mPowerState.prepareElectronBeam(
|
||||
mElectronBeamFadesConfig ?
|
||||
ElectronBeam.MODE_FADE :
|
||||
ElectronBeam.MODE_COOL_DOWN)
|
||||
} else if (mPowerState.prepareColorFade(mContext,
|
||||
mColorFadeFadesConfig ?
|
||||
ColorFade.MODE_FADE :
|
||||
ColorFade.MODE_COOL_DOWN)
|
||||
&& mPowerState.getScreenState() != Display.STATE_OFF) {
|
||||
mElectronBeamOffAnimator.start();
|
||||
mColorFadeOffAnimator.start();
|
||||
} else {
|
||||
mElectronBeamOffAnimator.end();
|
||||
mColorFadeOffAnimator.end();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -687,8 +690,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
// which will be handled asynchronously.
|
||||
if (mustNotify
|
||||
&& !mScreenOnWasBlocked
|
||||
&& !mElectronBeamOnAnimator.isStarted()
|
||||
&& !mElectronBeamOffAnimator.isStarted()
|
||||
&& !mColorFadeOnAnimator.isStarted()
|
||||
&& !mColorFadeOffAnimator.isStarted()
|
||||
&& !mScreenBrightnessRampAnimator.isAnimating()
|
||||
&& mPowerState.waitUntilClean(mCleanListener)) {
|
||||
synchronized (mLock) {
|
||||
@@ -936,13 +939,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
|
||||
mScreenBrightnessRampAnimator.isAnimating());
|
||||
|
||||
if (mElectronBeamOnAnimator != null) {
|
||||
pw.println(" mElectronBeamOnAnimator.isStarted()=" +
|
||||
mElectronBeamOnAnimator.isStarted());
|
||||
if (mColorFadeOnAnimator != null) {
|
||||
pw.println(" mColorFadeOnAnimator.isStarted()=" +
|
||||
mColorFadeOnAnimator.isStarted());
|
||||
}
|
||||
if (mElectronBeamOffAnimator != null) {
|
||||
pw.println(" mElectronBeamOffAnimator.isStarted()=" +
|
||||
mElectronBeamOffAnimator.isStarted());
|
||||
if (mColorFadeOffAnimator != null) {
|
||||
pw.println(" mColorFadeOffAnimator.isStarted()=" +
|
||||
mColorFadeOffAnimator.isStarted());
|
||||
}
|
||||
|
||||
if (mPowerState != null) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.display;
|
||||
|
||||
import com.android.server.lights.Light;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -56,7 +57,7 @@ final class DisplayPowerState {
|
||||
private final Choreographer mChoreographer;
|
||||
private final DisplayBlanker mBlanker;
|
||||
private final Light mBacklight;
|
||||
private final ElectronBeam mElectronBeam;
|
||||
private final ColorFade mColorFade;
|
||||
private final PhotonicModulator mPhotonicModulator;
|
||||
|
||||
private int mScreenState;
|
||||
@@ -64,19 +65,19 @@ final class DisplayPowerState {
|
||||
private boolean mScreenReady;
|
||||
private boolean mScreenUpdatePending;
|
||||
|
||||
private boolean mElectronBeamPrepared;
|
||||
private float mElectronBeamLevel;
|
||||
private boolean mElectronBeamReady;
|
||||
private boolean mElectronBeamDrawPending;
|
||||
private boolean mColorFadePrepared;
|
||||
private float mColorFadeLevel;
|
||||
private boolean mColorFadeReady;
|
||||
private boolean mColorFadeDrawPending;
|
||||
|
||||
private Runnable mCleanListener;
|
||||
|
||||
public DisplayPowerState(DisplayBlanker blanker, Light backlight, ElectronBeam electronBeam) {
|
||||
public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
|
||||
mHandler = new Handler(true /*async*/);
|
||||
mChoreographer = Choreographer.getInstance();
|
||||
mBlanker = blanker;
|
||||
mBacklight = backlight;
|
||||
mElectronBeam = electronBeam;
|
||||
mColorFade = electronBeam;
|
||||
mPhotonicModulator = new PhotonicModulator();
|
||||
|
||||
// At boot time, we know that the screen is on and the electron beam
|
||||
@@ -89,21 +90,21 @@ final class DisplayPowerState {
|
||||
mScreenBrightness = PowerManager.BRIGHTNESS_ON;
|
||||
scheduleScreenUpdate();
|
||||
|
||||
mElectronBeamPrepared = false;
|
||||
mElectronBeamLevel = 1.0f;
|
||||
mElectronBeamReady = true;
|
||||
mColorFadePrepared = false;
|
||||
mColorFadeLevel = 1.0f;
|
||||
mColorFadeReady = true;
|
||||
}
|
||||
|
||||
public static final FloatProperty<DisplayPowerState> ELECTRON_BEAM_LEVEL =
|
||||
public static final FloatProperty<DisplayPowerState> COLOR_FADE_LEVEL =
|
||||
new FloatProperty<DisplayPowerState>("electronBeamLevel") {
|
||||
@Override
|
||||
public void setValue(DisplayPowerState object, float value) {
|
||||
object.setElectronBeamLevel(value);
|
||||
object.setColorFadeLevel(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(DisplayPowerState object) {
|
||||
return object.getElectronBeamLevel();
|
||||
return object.getColorFadeLevel();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -176,26 +177,26 @@ final class DisplayPowerState {
|
||||
* @param mode The electron beam animation mode to prepare.
|
||||
* @return True if the electron beam was prepared.
|
||||
*/
|
||||
public boolean prepareElectronBeam(int mode) {
|
||||
if (!mElectronBeam.prepare(mode)) {
|
||||
mElectronBeamPrepared = false;
|
||||
mElectronBeamReady = true;
|
||||
public boolean prepareColorFade(Context context, int mode) {
|
||||
if (!mColorFade.prepare(context, mode)) {
|
||||
mColorFadePrepared = false;
|
||||
mColorFadeReady = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
mElectronBeamPrepared = true;
|
||||
mElectronBeamReady = false;
|
||||
scheduleElectronBeamDraw();
|
||||
mColorFadePrepared = true;
|
||||
mColorFadeReady = false;
|
||||
scheduleColorFadeDraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the electron beam surface.
|
||||
*/
|
||||
public void dismissElectronBeam() {
|
||||
mElectronBeam.dismiss();
|
||||
mElectronBeamPrepared = false;
|
||||
mElectronBeamReady = true;
|
||||
public void dismissColorFade() {
|
||||
mColorFade.dismiss();
|
||||
mColorFadePrepared = false;
|
||||
mColorFadeReady = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,20 +212,20 @@ final class DisplayPowerState {
|
||||
*
|
||||
* @param level The level, ranges from 0.0 (full off) to 1.0 (full on).
|
||||
*/
|
||||
public void setElectronBeamLevel(float level) {
|
||||
if (mElectronBeamLevel != level) {
|
||||
public void setColorFadeLevel(float level) {
|
||||
if (mColorFadeLevel != level) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setElectronBeamLevel: level=" + level);
|
||||
Slog.d(TAG, "setColorFadeLevel: level=" + level);
|
||||
}
|
||||
|
||||
mElectronBeamLevel = level;
|
||||
mColorFadeLevel = level;
|
||||
if (mScreenState != Display.STATE_OFF) {
|
||||
mScreenReady = false;
|
||||
scheduleScreenUpdate(); // update backlight brightness
|
||||
}
|
||||
if (mElectronBeamPrepared) {
|
||||
mElectronBeamReady = false;
|
||||
scheduleElectronBeamDraw();
|
||||
if (mColorFadePrepared) {
|
||||
mColorFadeReady = false;
|
||||
scheduleColorFadeDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,8 +233,8 @@ final class DisplayPowerState {
|
||||
/**
|
||||
* Gets the level of the electron beam steering current.
|
||||
*/
|
||||
public float getElectronBeamLevel() {
|
||||
return mElectronBeamLevel;
|
||||
public float getColorFadeLevel() {
|
||||
return mColorFadeLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,7 +244,7 @@ final class DisplayPowerState {
|
||||
* The listener always overrides any previously set listener.
|
||||
*/
|
||||
public boolean waitUntilClean(Runnable listener) {
|
||||
if (!mScreenReady || !mElectronBeamReady) {
|
||||
if (!mScreenReady || !mColorFadeReady) {
|
||||
mCleanListener = listener;
|
||||
return false;
|
||||
} else {
|
||||
@@ -259,13 +260,13 @@ final class DisplayPowerState {
|
||||
pw.println(" mScreenBrightness=" + mScreenBrightness);
|
||||
pw.println(" mScreenReady=" + mScreenReady);
|
||||
pw.println(" mScreenUpdatePending=" + mScreenUpdatePending);
|
||||
pw.println(" mElectronBeamPrepared=" + mElectronBeamPrepared);
|
||||
pw.println(" mElectronBeamLevel=" + mElectronBeamLevel);
|
||||
pw.println(" mElectronBeamReady=" + mElectronBeamReady);
|
||||
pw.println(" mElectronBeamDrawPending=" + mElectronBeamDrawPending);
|
||||
pw.println(" mColorFadePrepared=" + mColorFadePrepared);
|
||||
pw.println(" mColorFadeLevel=" + mColorFadeLevel);
|
||||
pw.println(" mColorFadeReady=" + mColorFadeReady);
|
||||
pw.println(" mColorFadeDrawPending=" + mColorFadeDrawPending);
|
||||
|
||||
mPhotonicModulator.dump(pw);
|
||||
mElectronBeam.dump(pw);
|
||||
mColorFade.dump(pw);
|
||||
}
|
||||
|
||||
private void scheduleScreenUpdate() {
|
||||
@@ -280,17 +281,17 @@ final class DisplayPowerState {
|
||||
mHandler.post(mScreenUpdateRunnable);
|
||||
}
|
||||
|
||||
private void scheduleElectronBeamDraw() {
|
||||
if (!mElectronBeamDrawPending) {
|
||||
mElectronBeamDrawPending = true;
|
||||
private void scheduleColorFadeDraw() {
|
||||
if (!mColorFadeDrawPending) {
|
||||
mColorFadeDrawPending = true;
|
||||
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,
|
||||
mElectronBeamDrawRunnable, null);
|
||||
mColorFadeDrawRunnable, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeCleanListenerIfNeeded() {
|
||||
final Runnable listener = mCleanListener;
|
||||
if (listener != null && mScreenReady && mElectronBeamReady) {
|
||||
if (listener != null && mScreenReady && mColorFadeReady) {
|
||||
mCleanListener = null;
|
||||
listener.run();
|
||||
}
|
||||
@@ -302,7 +303,7 @@ final class DisplayPowerState {
|
||||
mScreenUpdatePending = false;
|
||||
|
||||
int brightness = mScreenState != Display.STATE_OFF
|
||||
&& mElectronBeamLevel > 0f ? mScreenBrightness : 0;
|
||||
&& mColorFadeLevel > 0f ? mScreenBrightness : 0;
|
||||
if (mPhotonicModulator.setState(mScreenState, brightness)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Screen ready");
|
||||
@@ -317,16 +318,16 @@ final class DisplayPowerState {
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mElectronBeamDrawRunnable = new Runnable() {
|
||||
private final Runnable mColorFadeDrawRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mElectronBeamDrawPending = false;
|
||||
mColorFadeDrawPending = false;
|
||||
|
||||
if (mElectronBeamPrepared) {
|
||||
mElectronBeam.draw(mElectronBeamLevel);
|
||||
if (mColorFadePrepared) {
|
||||
mColorFade.draw(mColorFadeLevel);
|
||||
}
|
||||
|
||||
mElectronBeamReady = true;
|
||||
mColorFadeReady = true;
|
||||
invokeCleanListenerIfNeeded();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user