1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package androidx.constraintlayout.core.widgets;
17 
18 import static androidx.constraintlayout.core.widgets.ConstraintWidget.DIMENSION_HORIZONTAL;
19 import static androidx.constraintlayout.core.widgets.ConstraintWidget.DIMENSION_VERTICAL;
20 import static androidx.constraintlayout.core.widgets.ConstraintWidget.UNKNOWN;
21 
22 import androidx.constraintlayout.core.LinearSystem;
23 
24 /**
25  * Implements direct resolution without using the solver
26  */
27 public class Optimizer {
28 
29     // Optimization levels (mask)
30     public static final int OPTIMIZATION_NONE = 0;
31     public static final int OPTIMIZATION_DIRECT = 1;
32     public static final int OPTIMIZATION_BARRIER = 1 << 1;
33     public static final int OPTIMIZATION_CHAIN = 1 << 2;
34     public static final int OPTIMIZATION_DIMENSIONS = 1 << 3;
35     public static final int OPTIMIZATION_RATIO = 1 << 4;
36     public static final int OPTIMIZATION_GROUPS = 1 << 5;
37     public static final int OPTIMIZATION_GRAPH = 1 << 6;
38     public static final int OPTIMIZATION_GRAPH_WRAP = 1 << 7;
39     public static final int OPTIMIZATION_CACHE_MEASURES = 1 << 8;
40     public static final int OPTIMIZATION_DEPENDENCY_ORDERING = 1 << 9;
41     public static final int OPTIMIZATION_GROUPING = 1 << 10;
42     public static final int OPTIMIZATION_STANDARD = OPTIMIZATION_DIRECT
43             /* | OPTIMIZATION_GROUPING */
44             /* | OPTIMIZATION_DEPENDENCY_ORDERING */
45             | OPTIMIZATION_CACHE_MEASURES
46             /* | OPTIMIZATION_GRAPH */
47             /* | OPTIMIZATION_GRAPH_WRAP */
48             /* | OPTIMIZATION_DIMENSIONS */;
49 
50     // Internal use.
51     static boolean[] sFlags = new boolean[3];
52     static final int FLAG_USE_OPTIMIZE = 0; // simple enough to use optimizer
53     static final int FLAG_CHAIN_DANGLING = 1;
54     static final int FLAG_RECOMPUTE_BOUNDS = 2;
55 
56     /**
57      * Looks at optimizing match_parent
58      */
checkMatchParent(ConstraintWidgetContainer container, LinearSystem system, ConstraintWidget widget)59     static void checkMatchParent(ConstraintWidgetContainer container,
60             LinearSystem system,
61             ConstraintWidget widget) {
62         widget.mHorizontalResolution = UNKNOWN;
63         widget.mVerticalResolution = UNKNOWN;
64         if (container.mListDimensionBehaviors[DIMENSION_HORIZONTAL]
65                 != ConstraintWidget.DimensionBehaviour.WRAP_CONTENT
66                 && widget.mListDimensionBehaviors[DIMENSION_HORIZONTAL]
67                 == ConstraintWidget.DimensionBehaviour.MATCH_PARENT) {
68 
69             int left = widget.mLeft.mMargin;
70             int right = container.getWidth() - widget.mRight.mMargin;
71 
72             widget.mLeft.mSolverVariable = system.createObjectVariable(widget.mLeft);
73             widget.mRight.mSolverVariable = system.createObjectVariable(widget.mRight);
74             system.addEquality(widget.mLeft.mSolverVariable, left);
75             system.addEquality(widget.mRight.mSolverVariable, right);
76             widget.mHorizontalResolution = ConstraintWidget.DIRECT;
77             widget.setHorizontalDimension(left, right);
78         }
79         if (container.mListDimensionBehaviors[DIMENSION_VERTICAL]
80                 != ConstraintWidget.DimensionBehaviour.WRAP_CONTENT
81                 && widget.mListDimensionBehaviors[DIMENSION_VERTICAL]
82                 == ConstraintWidget.DimensionBehaviour.MATCH_PARENT) {
83 
84             int top = widget.mTop.mMargin;
85             int bottom = container.getHeight() - widget.mBottom.mMargin;
86 
87             widget.mTop.mSolverVariable = system.createObjectVariable(widget.mTop);
88             widget.mBottom.mSolverVariable = system.createObjectVariable(widget.mBottom);
89             system.addEquality(widget.mTop.mSolverVariable, top);
90             system.addEquality(widget.mBottom.mSolverVariable, bottom);
91             if (widget.mBaselineDistance > 0 || widget.getVisibility() == ConstraintWidget.GONE) {
92                 widget.mBaseline.mSolverVariable = system.createObjectVariable(widget.mBaseline);
93                 system.addEquality(widget.mBaseline.mSolverVariable,
94                         top + widget.mBaselineDistance);
95             }
96             widget.mVerticalResolution = ConstraintWidget.DIRECT;
97             widget.setVerticalDimension(top, bottom);
98         }
99     }
100 
101     // @TODO: add description
enabled(int optimizationLevel, int optimization)102     public static final boolean enabled(int optimizationLevel, int optimization) {
103         return (optimizationLevel & optimization) == optimization;
104     }
105 }
106