VectorDrawable.h revision 23c38a9ed9c28a9fda438e7d30532aad7a3844f7
14bbc2931263b232fba61807fca00e127573eff42Doris Liu/* 24bbc2931263b232fba61807fca00e127573eff42Doris Liu * Copyright (C) 2015 The Android Open Source Project 34bbc2931263b232fba61807fca00e127573eff42Doris Liu * 44bbc2931263b232fba61807fca00e127573eff42Doris Liu * Licensed under the Apache License, Version 2.0 (the "License"); 54bbc2931263b232fba61807fca00e127573eff42Doris Liu * you may not use this file except in compliance with the License. 64bbc2931263b232fba61807fca00e127573eff42Doris Liu * You may obtain a copy of the License at 74bbc2931263b232fba61807fca00e127573eff42Doris Liu * 84bbc2931263b232fba61807fca00e127573eff42Doris Liu * http://www.apache.org/licenses/LICENSE-2.0 94bbc2931263b232fba61807fca00e127573eff42Doris Liu * 104bbc2931263b232fba61807fca00e127573eff42Doris Liu * Unless required by applicable law or agreed to in writing, software 114bbc2931263b232fba61807fca00e127573eff42Doris Liu * distributed under the License is distributed on an "AS IS" BASIS, 124bbc2931263b232fba61807fca00e127573eff42Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134bbc2931263b232fba61807fca00e127573eff42Doris Liu * See the License for the specific language governing permissions and 144bbc2931263b232fba61807fca00e127573eff42Doris Liu * limitations under the License. 154bbc2931263b232fba61807fca00e127573eff42Doris Liu */ 164bbc2931263b232fba61807fca00e127573eff42Doris Liu 174bbc2931263b232fba61807fca00e127573eff42Doris Liu#ifndef ANDROID_HWUI_VPATH_H 184bbc2931263b232fba61807fca00e127573eff42Doris Liu#define ANDROID_HWUI_VPATH_H 194bbc2931263b232fba61807fca00e127573eff42Doris Liu 20dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include "hwui/Canvas.h" 21fc9999505a36c66892d7ccce85187936105f4f36sergeyv#include "hwui/Bitmap.h" 221d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu#include "DisplayList.h" 23766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 244bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkBitmap.h> 254bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkColor.h> 261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu#include <SkColorFilter.h> 27c2de46fadd4ca9c6aa2d9dd7a65b161b28fc6f3bDoris Liu#include <SkCanvas.h> 284bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkMatrix.h> 294bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkPaint.h> 304bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkPath.h> 314bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkPathMeasure.h> 324bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <SkRect.h> 33dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu#include <SkShader.h> 3423c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev#include <SkSurface.h> 354bbc2931263b232fba61807fca00e127573eff42Doris Liu 364bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <cutils/compiler.h> 374bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <stddef.h> 384bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <vector> 394bbc2931263b232fba61807fca00e127573eff42Doris Liu#include <string> 404bbc2931263b232fba61807fca00e127573eff42Doris Liu 414bbc2931263b232fba61807fca00e127573eff42Doris Liunamespace android { 424bbc2931263b232fba61807fca00e127573eff42Doris Liunamespace uirenderer { 434bbc2931263b232fba61807fca00e127573eff42Doris Liu 4485d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu// Debug 4585d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu#if DEBUG_VECTOR_DRAWABLE 4685d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu #define VECTOR_DRAWABLE_LOGD(...) ALOGD(__VA_ARGS__) 4785d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu#else 4885d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu #define VECTOR_DRAWABLE_LOGD(...) 4985d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu#endif 5085d99528b23b5575d97f614fe25f839d19740abcTeng-Hui Zhu 514bbc2931263b232fba61807fca00e127573eff42Doris Liunamespace VectorDrawable { 5232d7cda0b89a114171f14de0753674090b3d75fcDoris Liu#define VD_SET_PRIMITIVE_FIELD_WITH_FLAG(field, value, flag) (VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(field, (value)) ? ((flag) = true, true) : false) 5332d7cda0b89a114171f14de0753674090b3d75fcDoris Liu#define VD_SET_PROP(field, value) ((value) != (field) ? ((field) = (value), true) : false) 5432d7cda0b89a114171f14de0753674090b3d75fcDoris Liu#define VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(field, value) ({ bool retVal = VD_SET_PROP((mPrimitiveFields.field), (value));\ 551d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); retVal;}) 5632d7cda0b89a114171f14de0753674090b3d75fcDoris Liu#define UPDATE_SKPROP(field, value) ({bool retVal = ((field) != (value)); if ((field) != (value)) SkRefCnt_SafeAssign((field), (value)); retVal;}) 574bbc2931263b232fba61807fca00e127573eff42Doris Liu 584bbc2931263b232fba61807fca00e127573eff42Doris Liu/* A VectorDrawable is composed of a tree of nodes. 594bbc2931263b232fba61807fca00e127573eff42Doris Liu * Each node can be a group node, or a path. 604bbc2931263b232fba61807fca00e127573eff42Doris Liu * A group node can have groups or paths as children, but a path node has 614bbc2931263b232fba61807fca00e127573eff42Doris Liu * no children. 624bbc2931263b232fba61807fca00e127573eff42Doris Liu * One example can be: 634bbc2931263b232fba61807fca00e127573eff42Doris Liu * Root Group 644bbc2931263b232fba61807fca00e127573eff42Doris Liu * / | \ 654bbc2931263b232fba61807fca00e127573eff42Doris Liu * Group Path Group 664bbc2931263b232fba61807fca00e127573eff42Doris Liu * / \ | 674bbc2931263b232fba61807fca00e127573eff42Doris Liu * Path Path Path 684bbc2931263b232fba61807fca00e127573eff42Doris Liu * 691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * VectorDrawables are drawn into bitmap caches first, then the caches are drawn to the given 701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * canvas with root alpha applied. Two caches are maintained for VD, one in UI thread, the other in 711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * Render Thread. A generation id is used to keep track of changes in the vector drawable tree. 721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * Each cache has their own generation id to track whether they are up to date with the latest 731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * change in the tree. 741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * 751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * Any property change to the vector drawable coming from UI thread (such as bulk setters to update 761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * all the properties, and viewport change, etc.) are only modifying the staging properties. The 771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * staging properties will then be marked dirty and will be pushed over to render thread properties 781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * at sync point. If staging properties are not dirty at sync point, we sync backwards by updating 791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * staging properties with render thread properties to reflect the latest animation value. 801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu * 814bbc2931263b232fba61807fca00e127573eff42Doris Liu */ 821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liuclass PropertyChangedListener { 841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liupublic: 851d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PropertyChangedListener(bool* dirty, bool* stagingDirty) 861d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu : mDirty(dirty), mStagingDirty(stagingDirty) {} 871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void onPropertyChanged() { 881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu *mDirty = true; 891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void onStagingPropertyChanged() { 911d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu *mStagingDirty = true; 921d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 931d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liuprivate: 941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool* mDirty; 951d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool* mStagingDirty; 961d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu}; 971d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 984bbc2931263b232fba61807fca00e127573eff42Doris Liuclass ANDROID_API Node { 994bbc2931263b232fba61807fca00e127573eff42Doris Liupublic: 1001d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu class Properties { 1011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu public: 102a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh explicit Properties(Node* node) : mNode(node) {} 1031d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu inline void onPropertyChanged() { 1041d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNode->onPropertyChanged(this); 1051d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1061d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu private: 1071d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Node* mNode; 1081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 1094bbc2931263b232fba61807fca00e127573eff42Doris Liu Node(const Node& node) { 1104bbc2931263b232fba61807fca00e127573eff42Doris Liu mName = node.mName; 1114bbc2931263b232fba61807fca00e127573eff42Doris Liu } 1124bbc2931263b232fba61807fca00e127573eff42Doris Liu Node() {} 113cc29a5dde1ef0a3cf0fcec10eb9d37d9e8fa3afbStan Iliev virtual void draw(SkCanvas* outCanvas, bool useStagingData) = 0; 1144bbc2931263b232fba61807fca00e127573eff42Doris Liu virtual void dump() = 0; 1154bbc2931263b232fba61807fca00e127573eff42Doris Liu void setName(const char* name) { 1164bbc2931263b232fba61807fca00e127573eff42Doris Liu mName = name; 1174bbc2931263b232fba61807fca00e127573eff42Doris Liu } 1181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void setPropertyChangedListener(PropertyChangedListener* listener) { 1191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener = listener; 1201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void onPropertyChanged(Properties* properties) = 0; 1224bbc2931263b232fba61807fca00e127573eff42Doris Liu virtual ~Node(){} 1231d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void syncProperties() = 0; 1244bbc2931263b232fba61807fca00e127573eff42Doris Liuprotected: 1254bbc2931263b232fba61807fca00e127573eff42Doris Liu std::string mName; 1261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PropertyChangedListener* mPropertyChangedListener = nullptr; 1274bbc2931263b232fba61807fca00e127573eff42Doris Liu}; 1284bbc2931263b232fba61807fca00e127573eff42Doris Liu 1294bbc2931263b232fba61807fca00e127573eff42Doris Liuclass ANDROID_API Path : public Node { 1304bbc2931263b232fba61807fca00e127573eff42Doris Liupublic: 1314bbc2931263b232fba61807fca00e127573eff42Doris Liu struct ANDROID_API Data { 1324bbc2931263b232fba61807fca00e127573eff42Doris Liu std::vector<char> verbs; 1334bbc2931263b232fba61807fca00e127573eff42Doris Liu std::vector<size_t> verbSizes; 1344bbc2931263b232fba61807fca00e127573eff42Doris Liu std::vector<float> points; 1354bbc2931263b232fba61807fca00e127573eff42Doris Liu bool operator==(const Data& data) const { 1364bbc2931263b232fba61807fca00e127573eff42Doris Liu return verbs == data.verbs && verbSizes == data.verbSizes 1374bbc2931263b232fba61807fca00e127573eff42Doris Liu && points == data.points; 1384bbc2931263b232fba61807fca00e127573eff42Doris Liu } 1394bbc2931263b232fba61807fca00e127573eff42Doris Liu }; 1401d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1411d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu class PathProperties : public Properties { 1421d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu public: 143a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh explicit PathProperties(Node* node) : Properties(node) {} 1441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void syncProperties(const PathProperties& prop) { 1451d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mData = prop.mData; 1461d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 1471d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setData(const Data& data) { 1491d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Updates the path data. Note that we don't generate a new Skia path right away 1501d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // because there are cases where the animation is changing the path data, but the view 1511d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // that hosts the VD has gone off screen, in which case we won't even draw. So we 1521d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // postpone the Skia path generation to the draw time. 1531d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (data == mData) { 1541d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return; 1551d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1561d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mData = data; 1571d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 1581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1591d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1601d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu const Data& getData() const { 1611d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mData; 1621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu private: 1641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Data mData; 1651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 1661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1674bbc2931263b232fba61807fca00e127573eff42Doris Liu Path(const Path& path); 1684bbc2931263b232fba61807fca00e127573eff42Doris Liu Path(const char* path, size_t strLength); 1694bbc2931263b232fba61807fca00e127573eff42Doris Liu Path() {} 1701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1714bbc2931263b232fba61807fca00e127573eff42Doris Liu void dump() override; 1721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void syncProperties() override; 1731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void onPropertyChanged(Properties* prop) override { 1741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (prop == &mStagingProperties) { 1751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mStagingPropertiesDirty = true; 1761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mPropertyChangedListener) { 1771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener->onStagingPropertyChanged(); 1781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } else if (prop == &mProperties){ 1801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mSkPathDirty = true; 1811d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mPropertyChangedListener) { 1821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener->onPropertyChanged(); 1831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1851d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 1861d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PathProperties* mutateStagingProperties() { return &mStagingProperties; } 1871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu const PathProperties* stagingProperties() { return &mStagingProperties; } 1881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // This should only be called from animations on RT 1901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PathProperties* mutateProperties() { return &mProperties; } 1914bbc2931263b232fba61807fca00e127573eff42Doris Liu 1924bbc2931263b232fba61807fca00e127573eff42Doris Liuprotected: 193cc29a5dde1ef0a3cf0fcec10eb9d37d9e8fa3afbStan Iliev virtual const SkPath& getUpdatedPath(bool useStagingData, SkPath* tempStagingPath); 1941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1951d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Internal data, render thread only. 1964bbc2931263b232fba61807fca00e127573eff42Doris Liu bool mSkPathDirty = true; 1971d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkPath mSkPath; 1981d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 1991d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liuprivate: 2001d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PathProperties mProperties = PathProperties(this); 2011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PathProperties mStagingProperties = PathProperties(this); 2021d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool mStagingPropertiesDirty = true; 2034bbc2931263b232fba61807fca00e127573eff42Doris Liu}; 2044bbc2931263b232fba61807fca00e127573eff42Doris Liu 2054bbc2931263b232fba61807fca00e127573eff42Doris Liuclass ANDROID_API FullPath: public Path { 2064bbc2931263b232fba61807fca00e127573eff42Doris Liupublic: 2071d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu class FullPathProperties : public Properties { 2081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu public: 2091d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu struct PrimitiveFields { 2101d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float strokeWidth = 0; 2111d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColor strokeColor = SK_ColorTRANSPARENT; 2121d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float strokeAlpha = 1; 2131d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColor fillColor = SK_ColorTRANSPARENT; 2141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float fillAlpha = 1; 2151d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float trimPathStart = 0; 2161d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float trimPathEnd = 1; 2171d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float trimPathOffset = 0; 2181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu int32_t strokeLineCap = SkPaint::Cap::kButt_Cap; 2191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu int32_t strokeLineJoin = SkPaint::Join::kMiter_Join; 2201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float strokeMiterLimit = 4; 2211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu int fillType = 0; /* non-zero or kWinding_FillType in Skia */ 2221d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 223a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh explicit FullPathProperties(Node* mNode) : Properties(mNode), mTrimDirty(false) {} 224ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu ~FullPathProperties() { 225ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu SkSafeUnref(fillGradient); 226ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu SkSafeUnref(strokeGradient); 227ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu } 2281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void syncProperties(const FullPathProperties& prop) { 2291d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields = prop.mPrimitiveFields; 2301d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTrimDirty = true; 231ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu UPDATE_SKPROP(fillGradient, prop.fillGradient); 232ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu UPDATE_SKPROP(strokeGradient, prop.strokeGradient); 2331d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 2341d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2351d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setFillGradient(SkShader* gradient) { 236ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu if(UPDATE_SKPROP(fillGradient, gradient)) { 2371d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 2381d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2391d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2401d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setStrokeGradient(SkShader* gradient) { 241ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu if(UPDATE_SKPROP(strokeGradient, gradient)) { 2421d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 2431d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2451d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkShader* getFillGradient() const { 2461d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return fillGradient; 2471d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkShader* getStrokeGradient() const { 2491d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return strokeGradient; 2501d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2511d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getStrokeWidth() const{ 2521d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.strokeWidth; 2531d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2541d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setStrokeWidth(float strokeWidth) { 25532d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(strokeWidth, strokeWidth); 2561d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2571d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColor getStrokeColor() const{ 2581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.strokeColor; 2591d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2601d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setStrokeColor(SkColor strokeColor) { 26132d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(strokeColor, strokeColor); 2621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getStrokeAlpha() const{ 2641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.strokeAlpha; 2651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setStrokeAlpha(float strokeAlpha) { 26732d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(strokeAlpha, strokeAlpha); 2681d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColor getFillColor() const { 2701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.fillColor; 2711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setFillColor(SkColor fillColor) { 27332d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(fillColor, fillColor); 2741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getFillAlpha() const{ 2761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.fillAlpha; 2771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setFillAlpha(float fillAlpha) { 27932d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(fillAlpha, fillAlpha); 2801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2811d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getTrimPathStart() const{ 2821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.trimPathStart; 2831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setTrimPathStart(float trimPathStart) { 28532d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_WITH_FLAG(trimPathStart, trimPathStart, mTrimDirty); 2861d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getTrimPathEnd() const{ 2881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.trimPathEnd; 2891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setTrimPathEnd(float trimPathEnd) { 29132d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_WITH_FLAG(trimPathEnd, trimPathEnd, mTrimDirty); 2921d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2931d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getTrimPathOffset() const{ 2941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.trimPathOffset; 2951d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 2961d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setTrimPathOffset(float trimPathOffset) { 29732d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_WITH_FLAG(trimPathOffset, trimPathOffset, mTrimDirty); 2981d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 299766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 3001d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getStrokeMiterLimit() const { 3011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.strokeMiterLimit; 3021d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3031d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getStrokeLineCap() const { 3041d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.strokeLineCap; 3051d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3061d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getStrokeLineJoin() const { 3071d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.strokeLineJoin; 3081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3091d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getFillType() const { 3101d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.fillType; 3111d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3121d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool copyProperties(int8_t* outProperties, int length) const; 3131d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void updateProperties(float strokeWidth, SkColor strokeColor, float strokeAlpha, 3141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColor fillColor, float fillAlpha, float trimPathStart, float trimPathEnd, 3151d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin, 3161d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu int fillType) { 3171d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.strokeWidth = strokeWidth; 3181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.strokeColor = strokeColor; 3191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.strokeAlpha = strokeAlpha; 3201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.fillColor = fillColor; 3211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.fillAlpha = fillAlpha; 3221d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.trimPathStart = trimPathStart; 3231d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.trimPathEnd = trimPathEnd; 3241d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.trimPathOffset = trimPathOffset; 3251d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.strokeMiterLimit = strokeMiterLimit; 3261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.strokeLineCap = strokeLineCap; 3271d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.strokeLineJoin = strokeLineJoin; 3281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.fillType = fillType; 3291d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTrimDirty = true; 3301d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 3311d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3321d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Set property values during animation 3331d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setColorPropertyValue(int propertyId, int32_t value); 3341d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setPropertyValue(int propertyId, float value); 3351d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool mTrimDirty; 3361d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu private: 3371d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu enum class Property { 3381d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu strokeWidth = 0, 3391d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu strokeColor, 3401d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu strokeAlpha, 3411d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu fillColor, 3421d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu fillAlpha, 3431d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu trimPathStart, 3441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu trimPathEnd, 3451d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu trimPathOffset, 3461d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu strokeLineCap, 3471d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu strokeLineJoin, 3481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu strokeMiterLimit, 3491d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu fillType, 3501d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu count, 3511d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 3521d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PrimitiveFields mPrimitiveFields; 353ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu SkShader* fillGradient = nullptr; 354ad21fe27627c8f4a1de886a2d1c5296694dc3501Doris Liu SkShader* strokeGradient = nullptr; 3551d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 356766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 3571d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Called from UI thread 3584bbc2931263b232fba61807fca00e127573eff42Doris Liu FullPath(const FullPath& path); // for cloning 3594bbc2931263b232fba61807fca00e127573eff42Doris Liu FullPath(const char* path, size_t strLength) : Path(path, strLength) {} 3604bbc2931263b232fba61807fca00e127573eff42Doris Liu FullPath() : Path() {} 361cc29a5dde1ef0a3cf0fcec10eb9d37d9e8fa3afbStan Iliev void draw(SkCanvas* outCanvas, bool useStagingData) override; 3621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void dump() override; 3631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu FullPathProperties* mutateStagingProperties() { return &mStagingProperties; } 3641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu const FullPathProperties* stagingProperties() { return &mStagingProperties; } 3651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 3661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // This should only be called from animations on RT 3671d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu FullPathProperties* mutateProperties() { return &mProperties; } 3681d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 3691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void syncProperties() override; 3701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void onPropertyChanged(Properties* properties) override { 3711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Path::onPropertyChanged(properties); 3721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (properties == &mStagingProperties) { 3731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mStagingPropertiesDirty = true; 3741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mPropertyChangedListener) { 3751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener->onStagingPropertyChanged(); 3761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } else if (properties == &mProperties) { 3781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mPropertyChangedListener) { 3791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener->onPropertyChanged(); 3801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3811d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 3824bbc2931263b232fba61807fca00e127573eff42Doris Liu } 383dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 3844bbc2931263b232fba61807fca00e127573eff42Doris Liuprotected: 385cc29a5dde1ef0a3cf0fcec10eb9d37d9e8fa3afbStan Iliev const SkPath& getUpdatedPath(bool useStagingData, SkPath* tempStagingPath) override; 3864bbc2931263b232fba61807fca00e127573eff42Doris Liuprivate: 3871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 3881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu FullPathProperties mProperties = FullPathProperties(this); 3891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu FullPathProperties mStagingProperties = FullPathProperties(this); 3901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool mStagingPropertiesDirty = true; 3911d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 3921d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Intermediate data for drawing, render thread only 3934bbc2931263b232fba61807fca00e127573eff42Doris Liu SkPath mTrimmedSkPath; 3941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 3954bbc2931263b232fba61807fca00e127573eff42Doris Liu}; 3964bbc2931263b232fba61807fca00e127573eff42Doris Liu 3974bbc2931263b232fba61807fca00e127573eff42Doris Liuclass ANDROID_API ClipPath: public Path { 3984bbc2931263b232fba61807fca00e127573eff42Doris Liupublic: 3994bbc2931263b232fba61807fca00e127573eff42Doris Liu ClipPath(const ClipPath& path) : Path(path) {} 4004bbc2931263b232fba61807fca00e127573eff42Doris Liu ClipPath(const char* path, size_t strLength) : Path(path, strLength) {} 4014bbc2931263b232fba61807fca00e127573eff42Doris Liu ClipPath() : Path() {} 402cc29a5dde1ef0a3cf0fcec10eb9d37d9e8fa3afbStan Iliev void draw(SkCanvas* outCanvas, bool useStagingData) override; 4034bbc2931263b232fba61807fca00e127573eff42Doris Liu}; 4044bbc2931263b232fba61807fca00e127573eff42Doris Liu 4054bbc2931263b232fba61807fca00e127573eff42Doris Liuclass ANDROID_API Group: public Node { 4064bbc2931263b232fba61807fca00e127573eff42Doris Liupublic: 4071d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu class GroupProperties : public Properties { 4081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu public: 409a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh explicit GroupProperties(Node* mNode) : Properties(mNode) {} 4101d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu struct PrimitiveFields { 4111d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float rotate = 0; 4121d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float pivotX = 0; 4131d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float pivotY = 0; 4141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float scaleX = 1; 4151d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float scaleY = 1; 4161d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float translateX = 0; 4171d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float translateY = 0; 4181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } mPrimitiveFields; 4191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void syncProperties(const GroupProperties& prop) { 4201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields = prop.mPrimitiveFields; 4211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 4221d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4231d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getRotation() const { 4241d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.rotate; 4251d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setRotation(float rotation) { 42732d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(rotate, rotation); 4281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4291d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getPivotX() const { 4301d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.pivotX; 4311d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4321d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setPivotX(float pivotX) { 43332d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(pivotX, pivotX); 4341d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4351d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getPivotY() const { 4361d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.pivotY; 4371d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4381d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setPivotY(float pivotY) { 43932d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(pivotY, pivotY); 4401d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4411d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getScaleX() const { 4421d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.scaleX; 4431d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setScaleX(float scaleX) { 44532d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(scaleX, scaleX); 4461d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4471d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getScaleY() const { 4481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.scaleY; 4491d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4501d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setScaleY(float scaleY) { 45132d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(scaleY, scaleY); 4521d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4531d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getTranslateX() const { 4541d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.translateX; 4551d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4561d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setTranslateX(float translateX) { 45732d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(translateX, translateX); 4581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4591d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getTranslateY() const { 4601d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mPrimitiveFields.translateY; 4611d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setTranslateY(float translateY) { 46332d7cda0b89a114171f14de0753674090b3d75fcDoris Liu VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(translateY, translateY); 4641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void updateProperties(float rotate, float pivotX, float pivotY, 4661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float scaleX, float scaleY, float translateX, float translateY) { 4671d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.rotate = rotate; 4681d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.pivotX = pivotX; 4691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.pivotY = pivotY; 4701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.scaleX = scaleX; 4711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.scaleY = scaleY; 4721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.translateX = translateX; 4731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPrimitiveFields.translateY = translateY; 4741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu onPropertyChanged(); 4751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 4761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setPropertyValue(int propertyId, float value); 4771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getPropertyValue(int propertyId) const; 4781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool copyProperties(float* outProperties, int length) const; 4791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu static bool isValidProperty(int propertyId); 4801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu private: 4811d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu enum class Property { 4821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu rotate = 0, 4831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu pivotX, 4841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu pivotY, 4851d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu scaleX, 4861d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu scaleY, 4871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu translateX, 4881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu translateY, 4891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Count of the properties, must be at the end. 4901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu count, 4911d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 492766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu }; 4931d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 4944bbc2931263b232fba61807fca00e127573eff42Doris Liu Group(const Group& group); 4954bbc2931263b232fba61807fca00e127573eff42Doris Liu Group() {} 4961d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void addChild(Node* child); 4971d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void setPropertyChangedListener(PropertyChangedListener* listener) override { 4981d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Node::setPropertyChangedListener(listener); 4991d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu for (auto& child : mChildren) { 5001d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu child->setPropertyChangedListener(listener); 5011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5024bbc2931263b232fba61807fca00e127573eff42Doris Liu } 5031d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void syncProperties() override; 5041d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu GroupProperties* mutateStagingProperties() { return &mStagingProperties; } 5051d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu const GroupProperties* stagingProperties() { return &mStagingProperties; } 5061d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5071d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // This should only be called from animations on RT 5081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu GroupProperties* mutateProperties() { return &mProperties; } 5091d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5101d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Methods below could be called from either UI thread or Render Thread. 511cc29a5dde1ef0a3cf0fcec10eb9d37d9e8fa3afbStan Iliev virtual void draw(SkCanvas* outCanvas, bool useStagingData) override; 5121d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void getLocalMatrix(SkMatrix* outMatrix, const GroupProperties& properties); 5134bbc2931263b232fba61807fca00e127573eff42Doris Liu void dump() override; 514766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu static bool isValidProperty(int propertyId); 5154bbc2931263b232fba61807fca00e127573eff42Doris Liu 5161d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu virtual void onPropertyChanged(Properties* properties) override { 5171d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (properties == &mStagingProperties) { 5181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mStagingPropertiesDirty = true; 5191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mPropertyChangedListener) { 5201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener->onStagingPropertyChanged(); 5211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5221d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } else { 5231d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mPropertyChangedListener) { 5241d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mPropertyChangedListener->onPropertyChanged(); 5251d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5271d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5294bbc2931263b232fba61807fca00e127573eff42Doris Liuprivate: 5301d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu GroupProperties mProperties = GroupProperties(this); 5311d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu GroupProperties mStagingProperties = GroupProperties(this); 5321d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool mStagingPropertiesDirty = true; 533ef062ebd20032efe697741d6c3dfd1faec54f590Doris Liu std::vector< std::unique_ptr<Node> > mChildren; 5344bbc2931263b232fba61807fca00e127573eff42Doris Liu}; 5354bbc2931263b232fba61807fca00e127573eff42Doris Liu 536766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuclass ANDROID_API Tree : public VirtualLightRefBase { 5374bbc2931263b232fba61807fca00e127573eff42Doris Liupublic: 538a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh explicit Tree(Group* rootNode) : mRootNode(rootNode) { 5391d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mRootNode->setPropertyChangedListener(&mPropertyChangedListener); 5401d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 541335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu 542335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu // Copy properties from the tree and use the give node as the root node 543335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu Tree(const Tree* copy, Group* rootNode) : Tree(rootNode) { 544335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu mStagingProperties.syncAnimatableProperties(*copy->stagingProperties()); 545335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu mStagingProperties.syncNonAnimatableProperties(*copy->stagingProperties()); 546335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu } 547f8d131cc8dc4ef675b8f8fc57dcc26062d575d32Doris Liu // Draws the VD onto a bitmap cache, then the bitmap cache will be rendered onto the input 548f8d131cc8dc4ef675b8f8fc57dcc26062d575d32Doris Liu // canvas. Returns the number of pixels needed for the bitmap cache. 549f8d131cc8dc4ef675b8f8fc57dcc26062d575d32Doris Liu int draw(Canvas* outCanvas, SkColorFilter* colorFilter, 5504bbc2931263b232fba61807fca00e127573eff42Doris Liu const SkRect& bounds, bool needsMirroring, bool canReuseCache); 5511d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void drawStaging(Canvas* canvas); 5524bbc2931263b232fba61807fca00e127573eff42Doris Liu 553fc9999505a36c66892d7ccce85187936105f4f36sergeyv Bitmap& getBitmapUpdateIfDirty(); 5544bbc2931263b232fba61807fca00e127573eff42Doris Liu void setAllowCaching(bool allowCaching) { 5554bbc2931263b232fba61807fca00e127573eff42Doris Liu mAllowCaching = allowCaching; 5564bbc2931263b232fba61807fca00e127573eff42Doris Liu } 557766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu SkPaint* getPaint(); 5581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void syncProperties() { 5591d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mStagingProperties.mNonAnimatablePropertiesDirty) { 5601d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mProperties.syncNonAnimatableProperties(mStagingProperties); 5611d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mStagingProperties.mNonAnimatablePropertiesDirty = false; 5621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mStagingProperties.mAnimatablePropertiesDirty) { 5651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mProperties.syncAnimatableProperties(mStagingProperties); 5661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } else { 5671d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mStagingProperties.syncAnimatableProperties(mProperties); 5681d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mStagingProperties.mAnimatablePropertiesDirty = false; 5701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mRootNode->syncProperties(); 5711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu class TreeProperties { 5741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu public: 575a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh explicit TreeProperties(Tree* tree) : mTree(tree) {} 5761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Properties that can only be modified by UI thread, therefore sync should 5771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // only go from UI to RT 5781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu struct NonAnimatableProperties { 5791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float viewportWidth = 0; 5801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float viewportHeight = 0; 5811d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkRect bounds; 5821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu int scaledWidth = 0; 5831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu int scaledHeight = 0; 5841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColorFilter* colorFilter = nullptr; 5851d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu ~NonAnimatableProperties() { 5861d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkSafeUnref(colorFilter); 5871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 5881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } mNonAnimatableProperties; 5891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool mNonAnimatablePropertiesDirty = true; 5901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5911d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float mRootAlpha = 1.0f; 5921d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool mAnimatablePropertiesDirty = true; 5931d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 5941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void syncNonAnimatableProperties(const TreeProperties& prop) { 5951d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // Copy over the data that can only be changed in UI thread 5961d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mNonAnimatableProperties.colorFilter != prop.mNonAnimatableProperties.colorFilter) { 5971d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkRefCnt_SafeAssign(mNonAnimatableProperties.colorFilter, 5981d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu prop.mNonAnimatableProperties.colorFilter); 5991d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6001d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatableProperties = prop.mNonAnimatableProperties; 6011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6021d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 6031d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setViewportSize(float width, float height) { 6041d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mNonAnimatableProperties.viewportWidth != width 6051d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu || mNonAnimatableProperties.viewportHeight != height) { 6061d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatablePropertiesDirty = true; 6071d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatableProperties.viewportWidth = width; 6081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatableProperties.viewportHeight = height; 6091d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTree->onPropertyChanged(this); 6101d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6111d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6121d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setBounds(const SkRect& bounds) { 6131d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (mNonAnimatableProperties.bounds != bounds) { 6141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatableProperties.bounds = bounds; 6151d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatablePropertiesDirty = true; 6161d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTree->onPropertyChanged(this); 6171d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 6201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setScaledSize(int width, int height) { 621037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu // If the requested size is bigger than what the bitmap was, then 622037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu // we increase the bitmap size to match. The width and height 623037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu // are bound by MAX_CACHED_BITMAP_SIZE. 624037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu if (mNonAnimatableProperties.scaledWidth < width 625037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu || mNonAnimatableProperties.scaledHeight < height) { 626037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu mNonAnimatableProperties.scaledWidth = std::max(width, 627037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu mNonAnimatableProperties.scaledWidth); 628037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu mNonAnimatableProperties.scaledHeight = std::max(height, 629037fc1815b0f69b0b24e68e16281b490bdeb1d56Teng-Hui Zhu mNonAnimatableProperties.scaledHeight); 6301d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatablePropertiesDirty = true; 6311d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTree->onPropertyChanged(this); 6321d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6331d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6341d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void setColorFilter(SkColorFilter* filter) { 6351d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (UPDATE_SKPROP(mNonAnimatableProperties.colorFilter, filter)) { 6361d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mNonAnimatablePropertiesDirty = true; 6371d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTree->onPropertyChanged(this); 6381d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6391d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6401d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkColorFilter* getColorFilter() const{ 6411d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mNonAnimatableProperties.colorFilter; 6421d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6431d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 6441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getViewportWidth() const { 6451d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mNonAnimatableProperties.viewportWidth; 6461d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6471d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getViewportHeight() const { 6481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mNonAnimatableProperties.viewportHeight; 6491d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6501d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getScaledWidth() const { 6511d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mNonAnimatableProperties.scaledWidth; 6521d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6531d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getScaledHeight() const { 6541d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mNonAnimatableProperties.scaledHeight; 6551d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6561d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void syncAnimatableProperties(const TreeProperties& prop) { 6571d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mRootAlpha = prop.mRootAlpha; 6581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6591d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu bool setRootAlpha(float rootAlpha) { 6601d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu if (rootAlpha != mRootAlpha) { 6611d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mAnimatablePropertiesDirty = true; 6621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mRootAlpha = rootAlpha; 6631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu mTree->onPropertyChanged(this); 6641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return true; 6651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return false; 6671d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6681d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu float getRootAlpha() const { return mRootAlpha;} 6691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu const SkRect& getBounds() const { 6701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu return mNonAnimatableProperties.bounds; 6711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 6721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Tree* mTree; 6731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu }; 6741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu void onPropertyChanged(TreeProperties* prop); 6751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu TreeProperties* mutateStagingProperties() { return &mStagingProperties; } 676335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu const TreeProperties* stagingProperties() const { return &mStagingProperties; } 6771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 6781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu // This should only be called from animations on RT 6791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu TreeProperties* mutateProperties() { return &mProperties; } 6804bbc2931263b232fba61807fca00e127573eff42Doris Liu 68123c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // called from RT only 68223c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev const TreeProperties& properties() const { return mProperties; } 68323c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev 68467ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu // This should always be called from RT. 6857c7052dd9bbfb2d98112975f7cbd2655212bf85bDoris Liu void markDirty() { mCache.dirty = true; } 68667ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu bool isDirty() const { return mCache.dirty; } 68767ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu bool getPropertyChangeWillBeConsumed() const { return mWillBeConsumed; } 68867ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; } 68967ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu 69023c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // Returns true if VD cache surface is big enough. This should always be called from RT and it 69123c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // works with Skia pipelines only. 69223c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev bool canReuseSurface() { 69323c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev SkSurface* surface = mCache.surface.get(); 69423c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev return surface && surface->width() >= mProperties.getScaledWidth() 69523c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev && surface->height() >= mProperties.getScaledHeight(); 69623c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev } 69723c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev 69823c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // Draws VD cache into a canvas. This should always be called from RT and it works with Skia 69923c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // pipelines only. 70023c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev void draw(SkCanvas* canvas); 70123c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev 70223c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // Draws VD into a GPU backed surface. If canReuseSurface returns false, then "surface" must 70323c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // contain a new surface. This should always be called from RT and it works with Skia pipelines 70423c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev // only. 70523c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev void updateCache(sk_sp<SkSurface> surface); 70623c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev 7074bbc2931263b232fba61807fca00e127573eff42Doris Liuprivate: 708fc9999505a36c66892d7ccce85187936105f4f36sergeyv struct Cache { 70923c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev sk_sp<Bitmap> bitmap; //used by HWUI pipeline and software 71023c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev //TODO: use surface instead of bitmap when drawing in software canvas 71123c38a9ed9c28a9fda438e7d30532aad7a3844f7Stan Iliev sk_sp<SkSurface> surface; //used only by Skia pipelines 712fc9999505a36c66892d7ccce85187936105f4f36sergeyv bool dirty = true; 713fc9999505a36c66892d7ccce85187936105f4f36sergeyv }; 7141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 7151d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu SkPaint* updatePaint(SkPaint* outPaint, TreeProperties* prop); 716fc9999505a36c66892d7ccce85187936105f4f36sergeyv bool allocateBitmapIfNeeded(Cache& cache, int width, int height); 717fc9999505a36c66892d7ccce85187936105f4f36sergeyv bool canReuseBitmap(Bitmap*, int width, int height); 718fc9999505a36c66892d7ccce85187936105f4f36sergeyv void updateBitmapCache(Bitmap& outCache, bool useStagingData); 7194bbc2931263b232fba61807fca00e127573eff42Doris Liu // Cap the bitmap size, such that it won't hurt the performance too much 7204bbc2931263b232fba61807fca00e127573eff42Doris Liu // and it won't crash due to a very large scale. 7214bbc2931263b232fba61807fca00e127573eff42Doris Liu // The drawable will look blurry above this size. 7224bbc2931263b232fba61807fca00e127573eff42Doris Liu const static int MAX_CACHED_BITMAP_SIZE; 7234bbc2931263b232fba61807fca00e127573eff42Doris Liu 7244bbc2931263b232fba61807fca00e127573eff42Doris Liu bool mAllowCaching = true; 725ef062ebd20032efe697741d6c3dfd1faec54f590Doris Liu std::unique_ptr<Group> mRootNode; 7261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 7271d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu TreeProperties mProperties = TreeProperties(this); 7281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu TreeProperties mStagingProperties = TreeProperties(this); 7291d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 7304bbc2931263b232fba61807fca00e127573eff42Doris Liu SkPaint mPaint; 7311d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu 7321d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Cache mStagingCache; 7331d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Cache mCache; 7344bbc2931263b232fba61807fca00e127573eff42Doris Liu 7351d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu PropertyChangedListener mPropertyChangedListener 7361d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu = PropertyChangedListener(&mCache.dirty, &mStagingCache.dirty); 73767ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu 73867ce99b66ebc816ae8bbc222db8f3695fb15495bDoris Liu mutable bool mWillBeConsumed = false; 7394bbc2931263b232fba61807fca00e127573eff42Doris Liu}; 7404bbc2931263b232fba61807fca00e127573eff42Doris Liu 7414bbc2931263b232fba61807fca00e127573eff42Doris Liu} // namespace VectorDrawable 7424bbc2931263b232fba61807fca00e127573eff42Doris Liu 7434bbc2931263b232fba61807fca00e127573eff42Doris Liutypedef VectorDrawable::Path::Data PathData; 7444bbc2931263b232fba61807fca00e127573eff42Doris Liu} // namespace uirenderer 7454bbc2931263b232fba61807fca00e127573eff42Doris Liu} // namespace android 7464bbc2931263b232fba61807fca00e127573eff42Doris Liu 7474bbc2931263b232fba61807fca00e127573eff42Doris Liu#endif // ANDROID_HWUI_VPATH_H 748