1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDisplayList.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateActive.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateBase.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateMaker.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDisplayApply.h"
15986ca61cf7be3ec590f8820e9b7ba042ac2948fereed#include "SkADrawable.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawGroup.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawMatrix.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkInterpolator.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h"
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) {
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDisplayList::~SkDisplayList() {
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::append(SkActive* active) {
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *fActiveList.append() = active;
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDisplayList::draw(SkAnimateMaker& maker, SkMSec inTime) {
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    validate();
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fInTime = inTime;
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool result = false;
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fInvalBounds.setEmpty();
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fDrawList.count()) {
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (SkActive** activePtr = fActiveList.begin(); activePtr < fActiveList.end(); activePtr++) {
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkActive* active = *activePtr;
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            active->reset();
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int index = 0; index < fDrawList.count(); index++) {
42986ca61cf7be3ec590f8820e9b7ba042ac2948fereed            SkADrawable* draw = fDrawList[index];
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            draw->initialize(); // allow matrices to reset themselves
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkASSERT(draw->isDrawable());
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            validate();
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            result |= draw->draw(maker);
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    validate();
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return result;
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
53986ca61cf7be3ec590f8820e9b7ba042ac2948fereedint SkDisplayList::findGroup(SkADrawable* match, SkTDDrawableArray** list,
54d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) {
552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    *parent = nullptr;
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *list = &fDrawList;
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *grandList = &fDrawList;
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SearchForMatch(match, list, parent, found, grandList);
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::hardReset() {
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fDrawList.reset();
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fActiveList.reset();
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDisplayList::onIRect(const SkIRect& r) {
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBounds = r;
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fDrawBounds;
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
71986ca61cf7be3ec590f8820e9b7ba042ac2948fereedint SkDisplayList::SearchForMatch(SkADrawable* match, SkTDDrawableArray** list,
72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) {
732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    *found = nullptr;
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < (*list)->count(); index++) {
75986ca61cf7be3ec590f8820e9b7ba042ac2948fereed        SkADrawable* draw = (**list)[index];
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (draw == match)
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return index;
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (draw->isApply()) {
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkApply* apply = (SkApply*) draw;
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (apply->scope == match)
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return index;
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (apply->scope->isGroup() && SearchGroupForMatch(apply->scope, match, list, parent, found, grandList, index))
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return index;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (apply->mode == SkApply::kMode_create) {
85986ca61cf7be3ec590f8820e9b7ba042ac2948fereed                for (SkADrawable** ptr = apply->fScopes.begin(); ptr < apply->fScopes.end(); ptr++) {
86986ca61cf7be3ec590f8820e9b7ba042ac2948fereed                    SkADrawable* scope = *ptr;
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    if (scope == match)
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        return index;
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    //perhaps should call SearchGroupForMatch here as well (on scope)
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
91d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            }
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
93d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (draw->isGroup() && SearchGroupForMatch(draw, match, list, parent, found, grandList, index))
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return index;
95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return -1;
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
100986ca61cf7be3ec590f8820e9b7ba042ac2948fereedbool SkDisplayList::SearchGroupForMatch(SkADrawable* draw, SkADrawable* match, SkTDDrawableArray** list,
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList, int &index) {
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkGroup* group = (SkGroup*) draw;
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (group->getOriginal() == match)
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkTDDrawableArray* saveList = *list;
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int groupIndex = group->findGroup(match, list, parent, found, grandList);
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (groupIndex >= 0) {
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                *found = group;
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                index = groupIndex;
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            *list = saveList;
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return false;
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::reset() {
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < fDrawList.count(); index++) {
118986ca61cf7be3ec590f8820e9b7ba042ac2948fereed        SkADrawable* draw = fDrawList[index];
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (draw->isApply() == false)
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            continue;
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkApply* apply = (SkApply*) draw;
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        apply->reset();
123d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::remove(SkActive* active) {
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int index = fActiveList.find(active);
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(index >= 0);
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fActiveList.remove(index);  // !!! could use shuffle instead
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(fActiveList.find(active) < 0);
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DUMP_ENABLED
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkDisplayList::fDumpIndex;
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkDisplayList::fIndent;
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::dump(SkAnimateMaker* maker) {
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fIndent = 0;
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    dumpInner(maker);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::dumpInner(SkAnimateMaker* maker) {
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < fDrawList.count(); index++) {
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fDumpIndex = index;
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fDrawList[fDumpIndex]->dump(maker);
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDisplayList::validate() {
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < fDrawList.count(); index++) {
154986ca61cf7be3ec590f8820e9b7ba042ac2948fereed        SkADrawable* draw = fDrawList[index];
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        draw->validate();
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
159