1 /*
2 * Copyright (C) 2011 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
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20
21 #include "LayerRejecter.h"
22
23 #include <gui/BufferItem.h>
24 #include <system/window.h>
25
26 #define DEBUG_RESIZE 0
27
28 namespace android {
29
LayerRejecter(Layer::State & front,Layer::State & current,bool & recomputeVisibleRegions,bool stickySet,const std::string & name,int32_t overrideScalingMode,bool transformToDisplayInverse)30 LayerRejecter::LayerRejecter(Layer::State& front, Layer::State& current,
31 bool& recomputeVisibleRegions, bool stickySet, const std::string& name,
32 int32_t overrideScalingMode, bool transformToDisplayInverse)
33 : mFront(front),
34 mCurrent(current),
35 mRecomputeVisibleRegions(recomputeVisibleRegions),
36 mStickyTransformSet(stickySet),
37 mName(name),
38 mOverrideScalingMode(overrideScalingMode),
39 mTransformToDisplayInverse(transformToDisplayInverse) {}
40
reject(const sp<GraphicBuffer> & buf,const BufferItem & item)41 bool LayerRejecter::reject(const sp<GraphicBuffer>& buf, const BufferItem& item) {
42 if (buf == nullptr) {
43 return false;
44 }
45
46 uint32_t bufWidth = buf->getWidth();
47 uint32_t bufHeight = buf->getHeight();
48
49 // check that we received a buffer of the right size
50 // (Take the buffer's orientation into account)
51 if (item.mTransform & ui::Transform::ROT_90) {
52 std::swap(bufWidth, bufHeight);
53 }
54
55 if (mTransformToDisplayInverse) {
56 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
57 if (invTransform & ui::Transform::ROT_90) {
58 std::swap(bufWidth, bufHeight);
59 }
60 }
61
62 int actualScalingMode = mOverrideScalingMode >= 0 ? mOverrideScalingMode : item.mScalingMode;
63 bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
64 if (mFront.active_legacy != mFront.requested_legacy) {
65 if (isFixedSize ||
66 (bufWidth == mFront.requested_legacy.w && bufHeight == mFront.requested_legacy.h)) {
67 // Here we pretend the transaction happened by updating the
68 // current and drawing states. Drawing state is only accessed
69 // in this thread, no need to have it locked
70 mFront.active_legacy = mFront.requested_legacy;
71
72 // We also need to update the current state so that
73 // we don't end-up overwriting the drawing state with
74 // this stale current state during the next transaction
75 //
76 // NOTE: We don't need to hold the transaction lock here
77 // because State::active_legacy is only accessed from this thread.
78 mCurrent.active_legacy = mFront.active_legacy;
79 mCurrent.modified = true;
80
81 // recompute visible region
82 mRecomputeVisibleRegions = true;
83
84 if (mFront.crop_legacy != mFront.requestedCrop_legacy) {
85 mFront.crop_legacy = mFront.requestedCrop_legacy;
86 mCurrent.crop_legacy = mFront.requestedCrop_legacy;
87 mRecomputeVisibleRegions = true;
88 }
89 }
90
91 ALOGD_IF(DEBUG_RESIZE,
92 "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
93 " drawing={ active_legacy ={ wh={%4u,%4u} crop_legacy={%4d,%4d,%4d,%4d} "
94 "(%4d,%4d) "
95 "}\n"
96 " requested_legacy={ wh={%4u,%4u} }}\n",
97 mName.c_str(), bufWidth, bufHeight, item.mTransform, item.mScalingMode,
98 mFront.active_legacy.w, mFront.active_legacy.h, mFront.crop_legacy.left,
99 mFront.crop_legacy.top, mFront.crop_legacy.right, mFront.crop_legacy.bottom,
100 mFront.crop_legacy.getWidth(), mFront.crop_legacy.getHeight(),
101 mFront.requested_legacy.w, mFront.requested_legacy.h);
102 }
103
104 if (!isFixedSize && !mStickyTransformSet) {
105 if (mFront.active_legacy.w != bufWidth || mFront.active_legacy.h != bufHeight) {
106 // reject this buffer
107 ALOGE("[%s] rejecting buffer: "
108 "bufWidth=%d, bufHeight=%d, front.active_legacy.{w=%d, h=%d}",
109 mName.c_str(), bufWidth, bufHeight, mFront.active_legacy.w,
110 mFront.active_legacy.h);
111 return true;
112 }
113 }
114
115 // if the transparent region has changed (this test is
116 // conservative, but that's fine, worst case we're doing
117 // a bit of extra work), we latch the new one and we
118 // trigger a visible-region recompute.
119 //
120 // We latch the transparent region here, instead of above where we latch
121 // the rest of the geometry because it is only content but not necessarily
122 // resize dependent.
123 if (!mFront.activeTransparentRegion_legacy.hasSameRects(
124 mFront.requestedTransparentRegion_legacy)) {
125 mFront.activeTransparentRegion_legacy = mFront.requestedTransparentRegion_legacy;
126
127 // We also need to update the current state so that
128 // we don't end-up overwriting the drawing state with
129 // this stale current state during the next transaction
130 //
131 // NOTE: We don't need to hold the transaction lock here
132 // because State::active_legacy is only accessed from this thread.
133 mCurrent.activeTransparentRegion_legacy = mFront.activeTransparentRegion_legacy;
134
135 // recompute visible region
136 mRecomputeVisibleRegions = true;
137 }
138
139 return false;
140 }
141
142 } // namespace android
143
144 // TODO(b/129481165): remove the #pragma below and fix conversion issues
145 #pragma clang diagnostic pop // ignored "-Wconversion"
146