Layer.cpp revision 6b44267a3beb457e220cad0666c039d3a765cdb2
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
2213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
359cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
400f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
43a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "SurfaceTextureLayer.h"
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
47875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
48875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
5913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
62a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mDebug(false),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mOpaqueLayer(true),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
71933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
72a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
734d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mClientRef(client)
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
83a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glGenTextures(1, &mTextureName);
844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        layerFlags = layer_state_t::eLayerHidden;
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
107e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
108e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
109a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef()
11096f0819f81293076e652792794a961543e6750d7Mathias Agopian{
111bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
1126710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
113bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
114a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian            GL_TEXTURE_EXTERNAL_OES, false, bq);
115b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
116bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
117bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
118bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setSynchronousMode(true);
1194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
120b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1217f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1227f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
123bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1247f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
125bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
126303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1276905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
130b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
13196f0819f81293076e652792794a961543e6750d7Mathias Agopian
1324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
13313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
13413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
13513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
13613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
137921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
13896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
13996f0819f81293076e652792794a961543e6750d7Mathias Agopian
14013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
14213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
14813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
152a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1533d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
155579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
156579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1576710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1586710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
16248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
163cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
16613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
16913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
17013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
17113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
17213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
17313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this surfaces pixel format
17613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    PixelFormatInfo info;
17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    status_t err = getPixelFormatInfo(format, &info);
17813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (err) {
17913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("unsupported pixelformat %d", format);
18013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return err;
18113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
20613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
215882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
219882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
222882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
226a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
230a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
233582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
234582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
2354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<BufferQueue> Layer::getBufferQueue() const {
2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return mSurfaceFlingerConsumer->getBufferQueue();
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
24113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
24213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
243a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
244a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
245a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
246f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
247f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
248a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
249f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
250a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
251a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
252a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
254a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
256f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
257f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
258f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
259f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
260f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
261f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
262f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
263f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
264f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
265f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
266f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
267f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
268f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
269f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
27013127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
27413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2766c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
277f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return reduce(win, s.activeTransparentRegion);
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2806b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
2836b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
28613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
2871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
28813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
2916b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
2926b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
2936b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
2946b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect activeCrop(s.transform.transform(s.active.crop));
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // paranoia: make sure the window-crop is constrained in the
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // window's bounds
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
303f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
304f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
305f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3106b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
31813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
32013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                invTransform, s.active.w, s.active.h);
32113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3226b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3246b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
32513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3266b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetL = winCrop.left                 * xScale;
3276b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetT = winCrop.top                  * yScale;
3286b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetR = (winWidth  - winCrop.right ) * xScale;
3296b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetB = (winHeight - winCrop.bottom) * yScale;
33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
33413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
33513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
33613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
33713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
33813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
3404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
3414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
342a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
34313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
344a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
3453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
3463e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
347a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
348dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
349dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
350dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
351dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
35213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
3531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!isOpaque() || s.alpha != 0xFF) {
35513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
35813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
35913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect frame(s.transform.transform(computeBounds()));
36313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
36413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
36513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
36613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
3679f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
3689f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
36929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
37029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
37129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
37229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
37329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
37429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
37529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
37629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
37729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
37813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform transform(tr * s.transform * bufferOrientation);
37929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
38029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
38113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
38213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
38313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
3843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
385a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
387a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
388a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
389a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
3904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
391d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
39513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
39713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
39813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
39913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
40013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4013e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
4023e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
40371e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    layer.setBuffer(mActiveBuffer);
404c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
405dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
4064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
407d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
408c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
409d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
410d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
411d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
412d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
413d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
414bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
4151df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
416c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
417dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
418dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
419dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
420dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
421dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
422c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
423c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
424c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    onDraw(hw, clip);
43113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
43213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
43313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw) {
43413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    onDraw( hw, Region(hw->bounds()) );
43513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
43613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4391c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4401c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
441a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
443179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
444179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
445179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
446179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
447179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
448179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
449179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
450179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
451179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
452f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
453f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
454179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
455179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
45613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
45713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
458179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
4594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
460179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
461179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
462179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
463179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
4641b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
465179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
468a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
46997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
47097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
471bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
472bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
47397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
474dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
475dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
476dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
477dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
478dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
479dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
480875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
481875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
482dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
483cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
484eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
485cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
486cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
487cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
488bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
489bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
490cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
491cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
493a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
494875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
495a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
4961b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
497875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
50113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
50213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
50313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
50413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    LayerMesh mesh;
50513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    computeGeometry(hw, &mesh);
50613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
507875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mFlinger->getRenderEngine().clearWithColor(
508875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mesh.getVertices(), mesh.getVertexCount(),
509875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        red, green, blue, alpha);
51013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
51113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
51613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
51713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::drawWithOpenGL(
51813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
51913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t fbHeight = hw->getHeight();
5201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
52113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
52213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    LayerMesh mesh;
52313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    computeGeometry(hw, &mesh);
52413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
52513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
52613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
52713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
52813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
52913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
53013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
53113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
53213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
53313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
53413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is suspend is wether we should ignore this problem or revert to
53513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
53613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
53713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
53813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
53913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
54013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
54113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    GLfloat left   = GLfloat(win.left)   / GLfloat(s.active.w);
54213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    GLfloat top    = GLfloat(win.top)    / GLfloat(s.active.h);
54313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    GLfloat right  = GLfloat(win.right)  / GLfloat(s.active.w);
54413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
54513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
546875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
547875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
548875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    float texCoords[4][2];
549875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[0][0] = left;
550875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[0][1] = top;
551875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[1][0] = left;
552875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[1][1] = bottom;
553875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[2][0] = right;
554875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[2][1] = bottom;
555875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[3][0] = right;
556875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    texCoords[3][1] = top;
55713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    for (int i = 0; i < 4; i++) {
558875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        texCoords[i][1] = 1.0f - texCoords[i][1];
55913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
56013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
561875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
562875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
563875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
564875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
56513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
56613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
56713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
56813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
57013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
57113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
57213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
57313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
57413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
575ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
576ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
577ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
578ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
579ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
580ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
581ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
582a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format)
583ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
584a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
585a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
586ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
587a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    PixelFormatInfo info;
588a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
589a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // in case of error (unknown format), we assume no blending
590a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return (err || info.h_alpha <= info.l_alpha);
591ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
592ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
59313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
59413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
59513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
59613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
59713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
59813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
5991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
60013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform tr(hw->getTransform() * s.transform);
60113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
60213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
6066c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
607f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
60813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mesh) {
60913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        tr.transform(mesh->mVertices[0], win.left,  win.top);
61013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        tr.transform(mesh->mVertices[1], win.left,  win.bottom);
61113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        tr.transform(mesh->mVertices[2], win.right, win.bottom);
61213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        tr.transform(mesh->mVertices[3], win.right, win.top);
61313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        for (size_t i=0 ; i<4 ; i++) {
61413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
61513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
61613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
61713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
618ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
619a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
620a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
621a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
622a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
623db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
624a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
625db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
626a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
627a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
628a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
629a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
630a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
631a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
6327a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
6337a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
634a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
6357a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
6367a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
6377a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
638b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
63913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
64013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
64113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
64213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
64313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
64413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
64513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
64613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
64713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
64813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
64913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
65113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
65213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
65313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
65413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
65513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
65713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
65813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
65913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
66013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
66113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
66213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
66313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
66413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
66513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
66613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
66713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
66813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
66913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
67013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
67113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
6721c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6731c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
6741eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
6751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
6781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
679a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
680a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
681cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
6829d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
6836905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
684419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
685419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
686419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
687419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
6881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
6891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
6901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
6911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
6921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
6931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
6941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
6951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
6961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
6971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
6981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
6991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
7001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
7011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
7021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
7031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
7041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
7051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
7061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
7071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
7081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
7091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
7101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
7111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
7121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
7131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
7141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
7151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
7161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
717a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
7182a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
7192a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
720bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
7211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
723cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
7240cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
7250cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
7271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
7280cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7290cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
73013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
7310cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
7320cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
7330cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
7340cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
7350cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
7360cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
7370cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
7380cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7390cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
7400cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
7410cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
7420cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
74413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
74613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
7471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
7481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
75013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
7621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
7631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
76913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
774a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
775a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
77813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
78413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
78513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
78713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
78813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
79013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
79113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
79213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
79613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
80213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
80313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
80413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
80513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
80613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
80713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
80913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
81013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
81113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
81213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
81313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
81513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
81613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
81813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
82113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
8242ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
853a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
854a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8594d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
8604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
8614d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
864d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
865d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
866bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
86782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
86882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
869bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
870789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
87182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
87282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
87382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
87482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
87582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
87682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
87782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
878d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
87982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
880789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
88182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
88282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
88382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
88482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
88582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
88682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
88782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
88882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
88982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
890d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
891d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
892d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
893d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
894da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
89513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
89613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
89713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            && (mActiveBuffer != NULL);
898da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
899da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
9004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9021c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9031c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
9044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
9053d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
90699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
90799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
90899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
90999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
91099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
91199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
9124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
91499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
91599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
916351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
917db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
918351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
919db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
9203d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        // signal another event if we have more frames pending
9213d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        if (android_atomic_dec(&mQueuedFrames) > 1) {
92299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mFlinger->signalLayerUpdate();
9233d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        }
9243d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis
925bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
9262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
9272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
9282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
9292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
9302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
9312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
9322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
9332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
9342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
9362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    const BufferQueue::BufferItem& item) {
9372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
9382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
9392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
9422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
9432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
9452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
9462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
9472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
9482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
9512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
9522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
9542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
9552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
9562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
9572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
9582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
9592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
9602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
9612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
9632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
9642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
9652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
9662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
9672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
9682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
9692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
9712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
9722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
9732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
9756905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
9762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
9772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
9786905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
9792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
9802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
9812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
9822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
9832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
9842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
9852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
9862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
9872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
9882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
9892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
9902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
9912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
9922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
9932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
9962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
9972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
9984824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
9992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
10002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10022ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10032ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
10042ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
10052ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
10062ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
10072ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
10082ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
10092ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
10106c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10116c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
10126c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
10136c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
10146c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
10156c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
10166c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
10176c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
10186c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10196c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
10202ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
10212ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
10222ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
10242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
10262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
10292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
1030bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
1031a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1032a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
10334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1034a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1035d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1036351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1037bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1038e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1039e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
10404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1041e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1042da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
10434824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1044702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1045e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
10462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
10472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1048ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
10492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1050702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1051bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1052bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1053bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1054702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1055702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1056702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1057702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1058702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1059702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1060702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1061ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1062702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1063702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1064702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1065e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1066e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1067702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1068702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1069ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1070702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1071702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1072702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1073702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1074702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
1075702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1076702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1077702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
10784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
10791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(getDrawingState());
10801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
10811c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
10824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
10831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
108913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
109013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
109113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
109213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
109313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
109413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
109513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
109613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
109713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
109813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
109913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
110013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
110113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
110213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
110313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
110413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
110513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
110613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
110713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
110813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
110913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
111013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
111113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
111213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
111313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
111413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
111513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
111613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
111713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
11191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
11201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
112374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
112513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
11263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
112713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11282ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
112913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
113013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
113274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
113313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
113413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
113513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            isOpaque(), contentDirty,
114113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
114413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
11451b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1146a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1147a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
11481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
11491b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
11501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
11511b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
11531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
115474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
11551b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1156ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
11576905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
11596905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
11601b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
116274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1163bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1164d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1165d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
116674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid Layer::dumpStats(String8& result) const {
116782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
116882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
116982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
117013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearStats() {
117182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
117225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
117325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
117413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
117713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1179b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1180b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
118113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1184a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1185a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
1190