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