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