blob: 095fed8418aa27326b815c5277aa3cf85e0f8cc5 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SurfaceFlinger"
18
19#include <stdlib.h>
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <utils/Errors.h>
24#include <utils/Log.h>
Mathias Agopian0d1318b2009-03-27 17:58:20 -070025#include <utils/StopWatch.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026
Mathias Agopian0d1318b2009-03-27 17:58:20 -070027#include "BlurFilter.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080028#include "LayerBase.h"
29#include "LayerOrientationAnim.h"
30#include "SurfaceFlinger.h"
31#include "DisplayHardware/DisplayHardware.h"
32#include "OrientationAnimation.h"
33
34namespace android {
35// ---------------------------------------------------------------------------
36
37const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
38const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
39
40// ---------------------------------------------------------------------------
41
Mathias Agopian0d1318b2009-03-27 17:58:20 -070042// Animation...
43const float DURATION = ms2ns(200);
44const float BOUNCES_PER_SECOND = 0.5f;
45//const float BOUNCES_AMPLITUDE = 1.0f/16.0f;
46const float BOUNCES_AMPLITUDE = 0;
47const float DIM_TARGET = 0.40f;
48//#define INTERPOLATED_TIME(_t) ((_t)*(_t))
49#define INTERPOLATED_TIME(_t) (_t)
50
51// ---------------------------------------------------------------------------
52
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053LayerOrientationAnim::LayerOrientationAnim(
54 SurfaceFlinger* flinger, DisplayID display,
55 OrientationAnimation* anim,
Mathias Agopian076b1cc2009-04-10 14:24:30 -070056 const sp<Buffer>& bitmapIn,
57 const sp<Buffer>& bitmapOut)
Mathias Agopian0d1318b2009-03-27 17:58:20 -070058 : LayerOrientationAnimBase(flinger, display), mAnim(anim),
59 mBitmapIn(bitmapIn), mBitmapOut(bitmapOut),
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080060 mTextureName(-1), mTextureNameIn(-1)
61{
Mathias Agopian0d1318b2009-03-27 17:58:20 -070062 // blur that texture.
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080063 mStartTime = systemTime();
64 mFinishTime = 0;
65 mOrientationCompleted = false;
66 mFirstRedraw = false;
67 mLastNormalizedTime = 0;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080068 mNeedsBlending = false;
Mathias Agopian0d1318b2009-03-27 17:58:20 -070069 mAlphaInLerp.set(1.0f, DIM_TARGET);
70 mAlphaOutLerp.set(0.5f, 1.0f);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080071}
72
73LayerOrientationAnim::~LayerOrientationAnim()
74{
75 if (mTextureName != -1U) {
76 LayerBase::deletedTextures.add(mTextureName);
77 }
78 if (mTextureNameIn != -1U) {
79 LayerBase::deletedTextures.add(mTextureNameIn);
80 }
81}
82
83bool LayerOrientationAnim::needsBlending() const
84{
85 return mNeedsBlending;
86}
87
88Point LayerOrientationAnim::getPhysicalSize() const
89{
90 const GraphicPlane& plane(graphicPlane(0));
91 const DisplayHardware& hw(plane.displayHardware());
92 return Point(hw.getWidth(), hw.getHeight());
93}
94
95void LayerOrientationAnim::validateVisibility(const Transform&)
96{
97 const Layer::State& s(drawingState());
98 const Transform tr(s.transform);
99 const Point size(getPhysicalSize());
100 uint32_t w = size.x;
101 uint32_t h = size.y;
102 mTransformedBounds = tr.makeBounds(w, h);
103 mLeft = tr.tx();
104 mTop = tr.ty();
105 transparentRegionScreen.clear();
106 mTransformed = true;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800107}
108
109void LayerOrientationAnim::onOrientationCompleted()
110{
111 mFinishTime = systemTime();
112 mOrientationCompleted = true;
113 mFirstRedraw = true;
114 mNeedsBlending = true;
115 mFlinger->invalidateLayerVisibility(this);
116}
117
118void LayerOrientationAnim::onDraw(const Region& clip) const
119{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800120 const nsecs_t now = systemTime();
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700121 float alphaIn, alphaOut;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800122
123 if (mOrientationCompleted) {
124 if (mFirstRedraw) {
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700125 mFirstRedraw = false;
126
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800127 // make a copy of what's on screen
128 copybit_image_t image;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700129 mBitmapOut->getBitmapSurface(&image);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800130 const DisplayHardware& hw(graphicPlane(0).displayHardware());
131 hw.copyBackToImage(image);
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700132
133 // and erase the screen for this round
134 glDisable(GL_BLEND);
135 glDisable(GL_DITHER);
136 glDisable(GL_SCISSOR_TEST);
137 glClearColor(0,0,0,0);
138 glClear(GL_COLOR_BUFFER_BIT);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800139
140 // FIXME: code below is gross
141 mNeedsBlending = false;
142 LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
143 mFlinger->invalidateLayerVisibility(self);
144 }
145
146 // make sure pick-up where we left off
147 const float duration = DURATION * mLastNormalizedTime;
148 const float normalizedTime = (float(now - mFinishTime) / duration);
149 if (normalizedTime <= 1.0f) {
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700150 const float interpolatedTime = INTERPOLATED_TIME(normalizedTime);
151 alphaIn = mAlphaInLerp.getOut();
152 alphaOut = mAlphaOutLerp(interpolatedTime);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800153 } else {
154 mAnim->onAnimationFinished();
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700155 alphaIn = mAlphaInLerp.getOut();
156 alphaOut = mAlphaOutLerp.getOut();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800157 }
158 } else {
159 const float normalizedTime = float(now - mStartTime) / DURATION;
160 if (normalizedTime <= 1.0f) {
161 mLastNormalizedTime = normalizedTime;
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700162 const float interpolatedTime = INTERPOLATED_TIME(normalizedTime);
163 alphaIn = mAlphaInLerp(interpolatedTime);
164 alphaOut = 0.0f;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800165 } else {
166 mLastNormalizedTime = 1.0f;
167 const float to_seconds = DURATION / seconds(1);
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700168 alphaIn = mAlphaInLerp.getOut();
169 if (BOUNCES_AMPLITUDE > 0.0f) {
170 const float phi = BOUNCES_PER_SECOND *
171 (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
172 if (alphaIn > 1.0f) alphaIn = 1.0f;
173 else if (alphaIn < 0.0f) alphaIn = 0.0f;
174 alphaIn += BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
175 }
176 alphaOut = 0.0f;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800177 }
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700178 mAlphaOutLerp.setIn(alphaIn);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800179 }
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700180 drawScaled(1.0f, alphaIn, alphaOut);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800181}
182
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700183void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800184{
185 copybit_image_t dst;
186 const GraphicPlane& plane(graphicPlane(0));
187 const DisplayHardware& hw(plane.displayHardware());
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700188 //hw.getDisplaySurface(&dst);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800189
190 // clear screen
191 // TODO: with update on demand, we may be able
192 // to not erase the screen at all during the animation
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700193 if (!mOrientationCompleted) {
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700194 if (scale==1.0f && (alphaIn>=1.0f || alphaOut>=1.0f)) {
195 // we don't need to erase the screen in that case
196 } else {
197 glDisable(GL_BLEND);
198 glDisable(GL_DITHER);
199 glDisable(GL_SCISSOR_TEST);
200 glClearColor(0,0,0,0);
201 glClear(GL_COLOR_BUFFER_BIT);
202 }
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700203 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800204
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700205 copybit_image_t src;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700206 mBitmapIn->getBitmapSurface(&src);
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700207
208 copybit_image_t srcOut;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700209 mBitmapOut->getBitmapSurface(&srcOut);
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700210
211 const int w = dst.w*scale;
212 const int h = dst.h*scale;
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700213 const int xc = uint32_t(dst.w-w)/2;
214 const int yc = uint32_t(dst.h-h)/2;
215 const copybit_rect_t drect = { xc, yc, xc+w, yc+h };
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800216 const copybit_rect_t srect = { 0, 0, src.w, src.h };
Mathias Agopian0d1318b2009-03-27 17:58:20 -0700217 const Region reg(Rect( drect.l, drect.t, drect.r, drect.b ));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800218
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700219 GGLSurface t;
220 t.version = sizeof(GGLSurface);
221 t.width = src.w;
222 t.height = src.h;
223 t.stride = src.w;
224 t.vstride= src.h;
225 t.format = src.format;
226 t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800227
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700228 Transform tr;
229 tr.set(scale,0,0,scale);
230 tr.set(xc, yc);
231
232 // FIXME: we should not access mVertices and mDrawingState like that,
233 // but since we control the animation, we know it's going to work okay.
234 // eventually we'd need a more formal way of doing things like this.
235 LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
236 tr.transform(self.mVertices[0], 0, 0);
237 tr.transform(self.mVertices[1], 0, src.h);
238 tr.transform(self.mVertices[2], src.w, src.h);
239 tr.transform(self.mVertices[3], src.w, 0);
240 if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
241 // Too slow to do this in software
242 self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800243 }
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700244
245 if (alphaIn > 0.0f) {
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700246 t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700247 if (UNLIKELY(mTextureNameIn == -1LU)) {
248 mTextureNameIn = createTexture();
249 GLuint w=0, h=0;
250 const Region dirty(Rect(t.width, t.height));
251 loadTexture(dirty, mTextureNameIn, t, w, h);
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700252 }
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700253 self.mDrawingState.alpha = int(alphaIn*255);
254 drawWithOpenGL(reg, mTextureNameIn, t);
255 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800256
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700257 if (alphaOut > 0.0f) {
258 t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset);
259 if (UNLIKELY(mTextureName == -1LU)) {
260 mTextureName = createTexture();
261 GLuint w=0, h=0;
262 const Region dirty(Rect(t.width, t.height));
263 loadTexture(dirty, mTextureName, t, w, h);
Mathias Agopian7c143aa2009-03-24 22:50:50 -0700264 }
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700265 self.mDrawingState.alpha = int(alphaOut*255);
266 drawWithOpenGL(reg, mTextureName, t);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800267 }
268}
269
270// ---------------------------------------------------------------------------
271
272}; // namespace android