| |
| /* |
| * Copyright 2006 The Android Open Source Project |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| |
| #include "SkDisplayList.h" |
| #include "SkAnimateActive.h" |
| #include "SkAnimateBase.h" |
| #include "SkAnimateMaker.h" |
| #include "SkDisplayApply.h" |
| #include "SkDrawable.h" |
| #include "SkDrawGroup.h" |
| #include "SkDrawMatrix.h" |
| #include "SkInterpolator.h" |
| #include "SkTime.h" |
| |
| SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) { |
| } |
| |
| SkDisplayList::~SkDisplayList() { |
| } |
| |
| void SkDisplayList::append(SkActive* active) { |
| *fActiveList.append() = active; |
| } |
| |
| bool SkDisplayList::draw(SkAnimateMaker& maker, SkMSec inTime) { |
| validate(); |
| fInTime = inTime; |
| bool result = false; |
| fInvalBounds.setEmpty(); |
| if (fDrawList.count()) { |
| for (SkActive** activePtr = fActiveList.begin(); activePtr < fActiveList.end(); activePtr++) { |
| SkActive* active = *activePtr; |
| active->reset(); |
| } |
| for (int index = 0; index < fDrawList.count(); index++) { |
| SkDrawable* draw = fDrawList[index]; |
| draw->initialize(); // allow matrices to reset themselves |
| SkASSERT(draw->isDrawable()); |
| validate(); |
| result |= draw->draw(maker); |
| } |
| } |
| validate(); |
| return result; |
| } |
| |
| int SkDisplayList::findGroup(SkDrawable* match, SkTDDrawableArray** list, |
| SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) { |
| *parent = NULL; |
| *list = &fDrawList; |
| *grandList = &fDrawList; |
| return SearchForMatch(match, list, parent, found, grandList); |
| } |
| |
| void SkDisplayList::hardReset() { |
| fDrawList.reset(); |
| fActiveList.reset(); |
| } |
| |
| bool SkDisplayList::onIRect(const SkIRect& r) { |
| fBounds = r; |
| return fDrawBounds; |
| } |
| |
| int SkDisplayList::SearchForMatch(SkDrawable* match, SkTDDrawableArray** list, |
| SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) { |
| *found = NULL; |
| for (int index = 0; index < (*list)->count(); index++) { |
| SkDrawable* draw = (**list)[index]; |
| if (draw == match) |
| return index; |
| if (draw->isApply()) { |
| SkApply* apply = (SkApply*) draw; |
| if (apply->scope == match) |
| return index; |
| if (apply->scope->isGroup() && SearchGroupForMatch(apply->scope, match, list, parent, found, grandList, index)) |
| return index; |
| if (apply->mode == SkApply::kMode_create) { |
| for (SkDrawable** ptr = apply->fScopes.begin(); ptr < apply->fScopes.end(); ptr++) { |
| SkDrawable* scope = *ptr; |
| if (scope == match) |
| return index; |
| //perhaps should call SearchGroupForMatch here as well (on scope) |
| } |
| } |
| } |
| if (draw->isGroup() && SearchGroupForMatch(draw, match, list, parent, found, grandList, index)) |
| return index; |
| |
| } |
| return -1; |
| } |
| |
| bool SkDisplayList::SearchGroupForMatch(SkDrawable* draw, SkDrawable* match, SkTDDrawableArray** list, |
| SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList, int &index) { |
| SkGroup* group = (SkGroup*) draw; |
| if (group->getOriginal() == match) |
| return true; |
| SkTDDrawableArray* saveList = *list; |
| int groupIndex = group->findGroup(match, list, parent, found, grandList); |
| if (groupIndex >= 0) { |
| *found = group; |
| index = groupIndex; |
| return true; |
| } |
| *list = saveList; |
| return false; |
| } |
| |
| void SkDisplayList::reset() { |
| for (int index = 0; index < fDrawList.count(); index++) { |
| SkDrawable* draw = fDrawList[index]; |
| if (draw->isApply() == false) |
| continue; |
| SkApply* apply = (SkApply*) draw; |
| apply->reset(); |
| } |
| } |
| |
| void SkDisplayList::remove(SkActive* active) { |
| int index = fActiveList.find(active); |
| SkASSERT(index >= 0); |
| fActiveList.remove(index); // !!! could use shuffle instead |
| SkASSERT(fActiveList.find(active) < 0); |
| } |
| |
| #ifdef SK_DUMP_ENABLED |
| int SkDisplayList::fDumpIndex; |
| int SkDisplayList::fIndent; |
| |
| void SkDisplayList::dump(SkAnimateMaker* maker) { |
| fIndent = 0; |
| dumpInner(maker); |
| } |
| |
| void SkDisplayList::dumpInner(SkAnimateMaker* maker) { |
| for (int index = 0; index < fDrawList.count(); index++) { |
| fDumpIndex = index; |
| fDrawList[fDumpIndex]->dump(maker); |
| } |
| } |
| |
| #endif |
| |
| #ifdef SK_DEBUG |
| void SkDisplayList::validate() { |
| for (int index = 0; index < fDrawList.count(); index++) { |
| SkDrawable* draw = fDrawList[index]; |
| draw->validate(); |
| } |
| } |
| #endif |