17b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard/*
27b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * Copyright (C) 2011 The Android Open Source Project
37b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard *
47b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * Licensed under the Apache License, Version 2.0 (the "License");
57b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * you may not use this file except in compliance with the License.
67b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * You may obtain a copy of the License at
77b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard *
87b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard *      http://www.apache.org/licenses/LICENSE-2.0
97b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard *
107b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * Unless required by applicable law or agreed to in writing, software
117b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * distributed under the License is distributed on an "AS IS" BASIS,
127b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * See the License for the specific language governing permissions and
147b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard * limitations under the License.
157b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard */
167b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
177b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard#include "LayerRejecter.h"
187b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
19a9347647eca3101c014be902b713772de3977d87Mathias Agopian#include <gui/BufferItem.h>
20a9347647eca3101c014be902b713772de3977d87Mathias Agopian
217b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard#include "clz.h"
227b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
237b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard#define DEBUG_RESIZE 0
247b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
257b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglardnamespace android {
267b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
277b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien SanglardLayerRejecter::LayerRejecter(Layer::State& front,
287b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                             Layer::State& current,
297b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                             bool& recomputeVisibleRegions,
307b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                             bool stickySet,
317b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                             const char* name,
327b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                             int32_t overrideScalingMode,
337b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                             bool& freezePositionUpdates)
347b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard  : mFront(front),
357b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    mCurrent(current),
367b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    mRecomputeVisibleRegions(recomputeVisibleRegions),
377b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    mStickyTransformSet(stickySet),
387b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    mName(name),
397b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    mOverrideScalingMode(overrideScalingMode),
407bf247e2db180da661b18084d50e0b389686fc0cRobert Carr    mFreezeGeometryUpdates(freezePositionUpdates) {}
417b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
427b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglardbool LayerRejecter::reject(const sp<GraphicBuffer>& buf, const BufferItem& item) {
437b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    if (buf == NULL) {
447b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        return false;
457b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    }
467b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
477b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    uint32_t bufWidth = buf->getWidth();
487b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    uint32_t bufHeight = buf->getHeight();
497b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
507b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    // check that we received a buffer of the right size
517b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    // (Take the buffer's orientation into account)
527b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    if (item.mTransform & Transform::ROT_90) {
537b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        swap(bufWidth, bufHeight);
547b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    }
557b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
567b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    int actualScalingMode = mOverrideScalingMode >= 0 ? mOverrideScalingMode : item.mScalingMode;
577b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
587b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    if (mFront.active != mFront.requested) {
597b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        if (isFixedSize || (bufWidth == mFront.requested.w && bufHeight == mFront.requested.h)) {
607b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // Here we pretend the transaction happened by updating the
617b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // current and drawing states. Drawing state is only accessed
627b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // in this thread, no need to have it locked
637b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            mFront.active = mFront.requested;
647b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
657b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // We also need to update the current state so that
667b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // we don't end-up overwriting the drawing state with
677b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // this stale current state during the next transaction
687b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            //
697b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // NOTE: We don't need to hold the transaction lock here
707b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // because State::active is only accessed from this thread.
717b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            mCurrent.active = mFront.active;
727b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            mCurrent.modified = true;
737b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
747b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // recompute visible region
757b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            mRecomputeVisibleRegions = true;
767bf247e2db180da661b18084d50e0b389686fc0cRobert Carr
777bf247e2db180da661b18084d50e0b389686fc0cRobert Carr            mFreezeGeometryUpdates = false;
787bf247e2db180da661b18084d50e0b389686fc0cRobert Carr
797bf247e2db180da661b18084d50e0b389686fc0cRobert Carr            if (mFront.crop != mFront.requestedCrop) {
807bf247e2db180da661b18084d50e0b389686fc0cRobert Carr                mFront.crop = mFront.requestedCrop;
817bf247e2db180da661b18084d50e0b389686fc0cRobert Carr                mCurrent.crop = mFront.requestedCrop;
827bf247e2db180da661b18084d50e0b389686fc0cRobert Carr                mRecomputeVisibleRegions = true;
837bf247e2db180da661b18084d50e0b389686fc0cRobert Carr            }
847bf247e2db180da661b18084d50e0b389686fc0cRobert Carr            if (mFront.finalCrop != mFront.requestedFinalCrop) {
857bf247e2db180da661b18084d50e0b389686fc0cRobert Carr                mFront.finalCrop = mFront.requestedFinalCrop;
867bf247e2db180da661b18084d50e0b389686fc0cRobert Carr                mCurrent.finalCrop = mFront.requestedFinalCrop;
877bf247e2db180da661b18084d50e0b389686fc0cRobert Carr                mRecomputeVisibleRegions = true;
887bf247e2db180da661b18084d50e0b389686fc0cRobert Carr            }
897b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        }
907b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
917b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        ALOGD_IF(DEBUG_RESIZE,
927b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
937b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) "
947b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 "}\n"
957b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 "            requested={ wh={%4u,%4u} }}\n",
967b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 mName, bufWidth, bufHeight, item.mTransform, item.mScalingMode, mFront.active.w,
977b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 mFront.active.h, mFront.crop.left, mFront.crop.top, mFront.crop.right,
987b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 mFront.crop.bottom, mFront.crop.getWidth(), mFront.crop.getHeight(),
997b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                 mFront.requested.w, mFront.requested.h);
1007b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    }
1017b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
1027b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    if (!isFixedSize && !mStickyTransformSet) {
1037b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        if (mFront.active.w != bufWidth || mFront.active.h != bufHeight) {
1047b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            // reject this buffer
1057b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            ALOGE("[%s] rejecting buffer: "
1067b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                  "bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1077b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard                  mName, bufWidth, bufHeight, mFront.active.w, mFront.active.h);
1087b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard            return true;
1097b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        }
1107b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    }
1117b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
1127b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    // if the transparent region has changed (this test is
1137b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    // conservative, but that's fine, worst case we're doing
1147b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    // a bit of extra work), we latch the new one and we
1157b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    // trigger a visible-region recompute.
1167bf247e2db180da661b18084d50e0b389686fc0cRobert Carr    //
1177bf247e2db180da661b18084d50e0b389686fc0cRobert Carr    // We latch the transparent region here, instead of above where we latch
1187bf247e2db180da661b18084d50e0b389686fc0cRobert Carr    // the rest of the geometry because it is only content but not necessarily
1197bf247e2db180da661b18084d50e0b389686fc0cRobert Carr    // resize dependent.
1207b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    if (!mFront.activeTransparentRegion.isTriviallyEqual(mFront.requestedTransparentRegion)) {
1217b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        mFront.activeTransparentRegion = mFront.requestedTransparentRegion;
1227b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
1237b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        // We also need to update the current state so that
1247b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        // we don't end-up overwriting the drawing state with
1257b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        // this stale current state during the next transaction
1267b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        //
1277b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        // NOTE: We don't need to hold the transaction lock here
1287b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        // because State::active is only accessed from this thread.
1297b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        mCurrent.activeTransparentRegion = mFront.activeTransparentRegion;
1307b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
1317b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        // recompute visible region
1327b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard        mRecomputeVisibleRegions = true;
1337b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    }
1347b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
1357b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard    return false;
1367b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard}
1377b1563a0e8e742315a16c9a7b27537dbcd13d09aFabien Sanglard
138a9347647eca3101c014be902b713772de3977d87Mathias Agopian}  // namespace android
139