Home | History | Annotate | Download | only in animator
      1 /* libs/graphics/animator/SkDisplayList.cpp
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include "SkDisplayList.h"
     19 #include "SkAnimateActive.h"
     20 #include "SkAnimateBase.h"
     21 #include "SkAnimateMaker.h"
     22 #include "SkDisplayApply.h"
     23 #include "SkDrawable.h"
     24 #include "SkDrawGroup.h"
     25 #include "SkDrawMatrix.h"
     26 #include "SkInterpolator.h"
     27 #include "SkTime.h"
     28 
     29 SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) {
     30 }
     31 
     32 SkDisplayList::~SkDisplayList() {
     33 }
     34 
     35 void SkDisplayList::append(SkActive* active) {
     36     *fActiveList.append() = active;
     37 }
     38 
     39 bool SkDisplayList::draw(SkAnimateMaker& maker, SkMSec inTime) {
     40     validate();
     41     fInTime = inTime;
     42     bool result = false;
     43     fInvalBounds.setEmpty();
     44     if (fDrawList.count()) {
     45         for (SkActive** activePtr = fActiveList.begin(); activePtr < fActiveList.end(); activePtr++) {
     46             SkActive* active = *activePtr;
     47             active->reset();
     48         }
     49         for (int index = 0; index < fDrawList.count(); index++) {
     50             SkDrawable* draw = fDrawList[index];
     51             draw->initialize(); // allow matrices to reset themselves
     52             SkASSERT(draw->isDrawable());
     53             validate();
     54             result |= draw->draw(maker);
     55         }
     56     }
     57     validate();
     58     return result;
     59 }
     60 
     61 int SkDisplayList::findGroup(SkDrawable* match, SkTDDrawableArray** list,
     62         SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) {
     63     *parent = NULL;
     64     *list = &fDrawList;
     65     *grandList = &fDrawList;
     66     return SearchForMatch(match, list, parent, found, grandList);
     67 }
     68 
     69 void SkDisplayList::hardReset() {
     70     fDrawList.reset();
     71     fActiveList.reset();
     72 }
     73 
     74 bool SkDisplayList::onIRect(const SkIRect& r) {
     75     fBounds = r;
     76     return fDrawBounds;
     77 }
     78 
     79 int SkDisplayList::SearchForMatch(SkDrawable* match, SkTDDrawableArray** list,
     80         SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) {
     81     *found = NULL;
     82     for (int index = 0; index < (*list)->count(); index++) {
     83         SkDrawable* draw = (**list)[index];
     84         if (draw == match)
     85             return index;
     86         if (draw->isApply()) {
     87             SkApply* apply = (SkApply*) draw;
     88             if (apply->scope == match)
     89                 return index;
     90             if (apply->scope->isGroup() && SearchGroupForMatch(apply->scope, match, list, parent, found, grandList, index))
     91                 return index;
     92             if (apply->mode == SkApply::kMode_create) {
     93                 for (SkDrawable** ptr = apply->fScopes.begin(); ptr < apply->fScopes.end(); ptr++) {
     94                     SkDrawable* scope = *ptr;
     95                     if (scope == match)
     96                         return index;
     97                     //perhaps should call SearchGroupForMatch here as well (on scope)
     98                 }
     99             }
    100         }
    101         if (draw->isGroup() && SearchGroupForMatch(draw, match, list, parent, found, grandList, index))
    102             return index;
    103 
    104     }
    105     return -1;
    106 }
    107 
    108 bool SkDisplayList::SearchGroupForMatch(SkDrawable* draw, SkDrawable* match, SkTDDrawableArray** list,
    109         SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList, int &index) {
    110             SkGroup* group = (SkGroup*) draw;
    111             if (group->getOriginal() == match)
    112                 return true;
    113             SkTDDrawableArray* saveList = *list;
    114             int groupIndex = group->findGroup(match, list, parent, found, grandList);
    115             if (groupIndex >= 0) {
    116                 *found = group;
    117                 index = groupIndex;
    118                 return true;
    119             }
    120             *list = saveList;
    121             return false;
    122         }
    123 
    124 void SkDisplayList::reset() {
    125     for (int index = 0; index < fDrawList.count(); index++) {
    126         SkDrawable* draw = fDrawList[index];
    127         if (draw->isApply() == false)
    128             continue;
    129         SkApply* apply = (SkApply*) draw;
    130         apply->reset();
    131     }
    132 }
    133 
    134 void SkDisplayList::remove(SkActive* active) {
    135     int index = fActiveList.find(active);
    136     SkASSERT(index >= 0);
    137     fActiveList.remove(index);  // !!! could use shuffle instead
    138     SkASSERT(fActiveList.find(active) < 0);
    139 }
    140 
    141 #ifdef SK_DUMP_ENABLED
    142 int SkDisplayList::fDumpIndex;
    143 int SkDisplayList::fIndent;
    144 
    145 void SkDisplayList::dump(SkAnimateMaker* maker) {
    146     fIndent = 0;
    147     dumpInner(maker);
    148 }
    149 
    150 void SkDisplayList::dumpInner(SkAnimateMaker* maker) {
    151     for (int index = 0; index < fDrawList.count(); index++) {
    152         fDumpIndex = index;
    153         fDrawList[fDumpIndex]->dump(maker);
    154     }
    155 }
    156 
    157 #endif
    158 
    159 #ifdef SK_DEBUG
    160 void SkDisplayList::validate() {
    161     for (int index = 0; index < fDrawList.count(); index++) {
    162         SkDrawable* draw = fDrawList[index];
    163         draw->validate();
    164     }
    165 }
    166 #endif
    167 
    168 
    169