Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 #include "AnimationThread.h"
     26 
     27 #include <utils/SystemClock.h>
     28 #include "ANPNativeWindow_npapi.h"
     29 
     30 extern ANPLogInterfaceV0           gLogI;
     31 extern ANPNativeWindowInterfaceV0  gNativeWindowI;
     32 
     33 AnimationThread::AnimationThread(NPP npp) : RenderingThread(npp) {
     34     m_counter = 0;
     35     m_lastPrintTime = android::uptimeMillis();
     36     m_executionTime = 0;
     37     m_idleTime = 0;
     38 
     39     m_x = m_y = 0;
     40     m_dx = 0;
     41     m_dy = 0;
     42 
     43     memset(&m_oval, 0, sizeof(m_oval));
     44 
     45     m_paint = new SkPaint;
     46     m_paint->setAntiAlias(true);
     47 
     48     m_bitmap = constructBitmap(0, 0);
     49     m_canvas = new SkCanvas(*m_bitmap);
     50 
     51     m_startExecutionTime = 0;
     52     m_startTime = android::uptimeMillis();
     53     m_stallTime = android::uptimeMillis();
     54 
     55 }
     56 
     57 AnimationThread::~AnimationThread() {
     58     delete m_paint;
     59     delete m_canvas;
     60     delete m_bitmap;
     61 }
     62 
     63 SkBitmap* AnimationThread::constructBitmap(int width, int height) {
     64     SkBitmap* bitmap = new SkBitmap;
     65     bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
     66     bitmap->allocPixels();
     67     bitmap->eraseColor(0x00000000);
     68     return bitmap;
     69 }
     70 
     71 static void bounce(float* x, float* dx, const float max) {
     72     *x += *dx;
     73     if (*x < 0) {
     74         *x = 0;
     75         if (*dx < 0) {
     76             *dx = -*dx;
     77         }
     78     } else if (*x > max) {
     79         *x = max;
     80         if (*dx > 0) {
     81             *dx = -*dx;
     82         }
     83     }
     84 }
     85 
     86 bool AnimationThread::threadLoop() {
     87     if (android::uptimeMillis() - m_stallTime < MS_PER_FRAME)
     88         return true;
     89     m_stallTime = android::uptimeMillis();
     90 
     91     m_idleTime += android::uptimeMillis() - m_startIdleTime;
     92     m_startExecutionTime = android::uptimeMillis();
     93 
     94     bool reCreateFlag = false;
     95     int width, height;
     96     getDimensions(width, height);
     97 
     98     if (m_bitmap->width() != width || m_bitmap->height() != height) {
     99         delete m_canvas;
    100         delete m_bitmap;
    101         m_bitmap = constructBitmap(width, height);
    102         m_canvas = new SkCanvas(*m_bitmap);
    103 
    104         // change the ball's speed to match the size
    105         m_dx = width * .005f;
    106         m_dy = height * .007f;
    107         reCreateFlag = true;
    108     }
    109 
    110     // setup variables
    111     const float OW = width * .125f;
    112     const float OH = height * .125f;
    113 
    114     // clear the old oval
    115     m_bitmap->eraseColor(0x880000FF);
    116 
    117     // update the coordinates of the oval
    118     bounce(&m_x, &m_dx, width - OW);
    119     bounce(&m_y, &m_dy, height - OH);
    120 
    121     // draw the new oval
    122     m_oval.fLeft = m_x;
    123     m_oval.fTop = m_y;
    124     m_oval.fRight = m_x + OW;
    125     m_oval.fBottom = m_y + OH;
    126     m_paint->setColor(0xAAFF0000);
    127     m_canvas->drawOval(m_oval, *m_paint);
    128 
    129     if (!reCreateFlag) {
    130         updateNativeWindow(m_ANW, *m_bitmap);
    131     } else {
    132         setupNativeWindow(m_ANW, *m_bitmap);
    133     }
    134 
    135     m_executionTime += android::uptimeMillis() - m_startExecutionTime;
    136     m_counter++;
    137 
    138     if (android::uptimeMillis() - m_lastPrintTime > 5000) {
    139         float fps = m_counter / ((android::uptimeMillis() - m_startTime) / 1000);
    140         float spf = ((android::uptimeMillis() - m_startTime)) / m_counter;
    141         float lpf = (m_idleTime) / m_counter;
    142         float exe = (m_executionTime) / m_counter;
    143         gLogI.log(kError_ANPLogType, "TEXT: counter(%d) fps(%f) spf(%f) lock(%f) execution(%f)\n", (int)m_counter, fps, spf, lpf, exe);
    144         m_lastPrintTime = android::uptimeMillis();
    145 
    146         m_counter = 0;
    147         m_executionTime = 0;
    148         m_idleTime = 0;
    149         m_startExecutionTime = 0;
    150         m_startTime = android::uptimeMillis();
    151     }
    152 
    153     m_startIdleTime = android::uptimeMillis(); // count delay between frames
    154     return true;
    155 }
    156