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