Layer.cpp revision 5cdc8994a0ecd751a6350b16a1bef8b6b0d09b11
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),
775cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
78b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mClientRef(client)
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
83a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        layerFlags = layer_state_t::eLayerHidden;
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1086547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1096547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
112e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
113e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
115bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
116db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mBufferQueue = new SurfaceTextureLayer(mFlinger);
1173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
118bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
119bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
1204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
121b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1227f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1237f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
124bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1257f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
127303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1286905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
131b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
13296f0819f81293076e652792794a961543e6750d7Mathias Agopian
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
13413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
13513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
13613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
13713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
138921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
14196f0819f81293076e652792794a961543e6750d7Mathias Agopian
14213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
15013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
154a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1553d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
15699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
157579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
158579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1606710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1616710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
16213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
163bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
16448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
165cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
16613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
16813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
17113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
17213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
17313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
17413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
17513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
17813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
17913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
18113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
209882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
213882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
216882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
219a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
220a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
224a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
227582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
228582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
229db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopiansp<IGraphicBufferProducer> Layer::getBufferQueue() const {
230db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    return mBufferQueue;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
23413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
237a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
238a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
239a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
240f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
241f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
242a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
244a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
245a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
246a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
247f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
248a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
250f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
251f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
252f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
254f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
255f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
256f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
257f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
258f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
259f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
260f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
261f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
262f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
263f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
26413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2706c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
271f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return reduce(win, s.activeTransparentRegion);
27213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2746b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
27513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
2776b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
27813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
2811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
28213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
2856b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
2866b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
2876b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
2886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
28913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect activeCrop(s.transform.transform(s.active.crop));
29013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
29113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
29213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
29313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // paranoia: make sure the window-crop is constrained in the
29413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // window's bounds
29513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
29613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
297f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
298f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
299f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3046b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
30513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
30613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                invTransform, s.active.w, s.active.h);
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3166b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3176b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3186b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3206b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetL = winCrop.left                 * xScale;
3216b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetT = winCrop.top                  * yScale;
3226b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetR = (winWidth  - winCrop.right ) * xScale;
3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetB = (winHeight - winCrop.bottom) * yScale;
32413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
32513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
32613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
32713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
32813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
32913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
33013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
3344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
3354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
336a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
33713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
338a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
3393e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
3403e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
341a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
342dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
343dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
344dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
345dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
3471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!isOpaque() || s.alpha != 0xFF) {
34913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
35013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
35113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
35213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
35413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
35513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect frame(s.transform.transform(computeBounds()));
35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
35813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
35913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
3619f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
3629f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
36329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
36429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
36529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
36629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
36729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
36829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
36929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
37029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
37129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform transform(tr * s.transform * bufferOrientation);
37329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
37429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
37513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
37613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
37713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
3783e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
379a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
38013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
381a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
382a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
383a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
3844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
385d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
39013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
39213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
39313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
39413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3953e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
3963e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
39771e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    layer.setBuffer(mActiveBuffer);
398c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
399dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
4004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
401d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
402c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
403d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
404d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
405d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
406d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
407d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
408bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
4091df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
410c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
411dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
412dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
413dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
414dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
415dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
416c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
417c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
418c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
41913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
42013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
42113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
42213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
42313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
42413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    onDraw(hw, clip);
42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw) {
42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    onDraw( hw, Region(hw->bounds()) );
42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4331c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
435a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
437179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
438179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
439179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
440179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
441179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
442179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
443179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
444179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
445179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
446f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
447f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
448179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
449179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
45013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
45113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
452179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
4534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
454179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
455179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
456179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
457179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
4581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
459179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
462a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
46397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
46497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
465bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
466bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
46797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
468dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
469dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
470dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
471dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
472dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
473dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
474875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
475875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
476dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
477cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
478eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
479cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
480cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
481cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
482bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
483bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
484cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
485cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
486875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
487a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
488875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
489a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
4901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
49513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
4963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        float red, float green, float blue, float alpha) const
49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
4985cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    computeGeometry(hw, mMesh);
4995cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    mFlinger->getRenderEngine().fillWithColor(mMesh, red, green, blue, alpha);
50013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
50113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
50213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
50313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
50413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
50513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
50613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
50713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::drawWithOpenGL(
50813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
50913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t fbHeight = hw->getHeight();
5101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
51113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
5125cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    computeGeometry(hw, mMesh);
51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
51613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
51713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
51813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
51913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
52013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
52113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
52213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
52313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is suspend is wether we should ignore this problem or revert to
52413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
52513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
52613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
52713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
52813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
52913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
5303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
5313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
5323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
5333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
53413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
535875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
536875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
5375cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    Mesh::VertexArray texCoords(mMesh.getTexCoordArray());
5385cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[0].s = left;
5395cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[0].t = 1.0f - top;
5405cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[1].s = left;
5415cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[1].t = 1.0f - bottom;
5425cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[2].s = right;
5435cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[2].t = 1.0f - bottom;
5445cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[3].s = right;
5455cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    texCoords[3].t = 1.0f - top;
54613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
547875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
548875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
5495cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
550875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
55113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
55213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
55313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
55413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
55513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
55613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
55713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
55813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
55913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
56013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
561ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
562ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
563ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
564ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
565ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
566ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
567ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
5685773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
570a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
571ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
5725773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
5735773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
5745773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
575dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
5765773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
5775773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
578dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
579ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
580ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
58113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
58213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
58313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
58413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
5853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
58613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
5871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
58813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform tr(hw->getTransform() * s.transform);
58913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
59013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
59113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
59213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
59313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
5946c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
595f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
5963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
5975cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    Mesh::VertexArray position(mesh.getPositionArray());
5985cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    tr.transform(position[0], win.left,  win.top);
5995cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    tr.transform(position[1], win.left,  win.bottom);
6005cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    tr.transform(position[2], win.right, win.bottom);
6015cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    tr.transform(position[3], win.right, win.top);
6023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
6035cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
606ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
607a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
608a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
609a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
610a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
611db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
612a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
613db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
614a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
615a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
616a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
617a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
618a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
619a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
6207a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
6217a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
622a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
6237a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
6247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
6257a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
626b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
62713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
62813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
62913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
63113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
63213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
63313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
63513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
63613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
63713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
63813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
63913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
64013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
64113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
64213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
64313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
64413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
64513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
64613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
64713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
64813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
64913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
65013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
65113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
65213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
65313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
65413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
65513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
65713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
65813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
65913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
6601c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6611c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
6621eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
6631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
6661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
667a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
668a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
669cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
6709d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
6716905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
672419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
673419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
674419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
675419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
6761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
6771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
6781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
6791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
6801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
6811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
6821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
6831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
6841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
6851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
6861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
6871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
6881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
6891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
6901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
6911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
6921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
6931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
6941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
6951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
6961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
6971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
6981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
6991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
7001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
7011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
7021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
7031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
7041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
705a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
7062a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
7072a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
708bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
7091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
711cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
7120cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
7130cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
7151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
7160cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7170cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
71813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
7190cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
7200cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
7210cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
7220cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
7230cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
7240cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
7250cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
7260cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7270cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
7280cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
7290cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
7300cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
73113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
73213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
73313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
73413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
7351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
7361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
73813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
74013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
74113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
74213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
74513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
74613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
74713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
74813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
74913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
7501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
7511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
75213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
75313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
75413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
762a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
763a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
76413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
76513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
76613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
76713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
76813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
76913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
77013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
77113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
77213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
77313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
77413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
77513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
77613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
77713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
77813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
77913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
78013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
78113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
78213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
78413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
78513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
78713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
78813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
79013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
79113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
79213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
79613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
80213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
80313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
80413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
80513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
80613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
80713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
80913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
81013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
81113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
8122ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
81313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
81413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
81513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
81613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
81813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
82113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
841a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
842a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8474d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
8484d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
8494d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
85099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
85199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
852d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
853d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
854bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
85582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
85682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
857bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
858789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
85982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
86082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
86182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
86282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
86382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
86482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
86582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
866d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
86782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
868789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
86982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
87082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
87182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
87282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
87382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
87482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
87582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
87682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
87782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
878d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
879d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
880d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
881d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
882da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            && (mActiveBuffer != NULL);
886da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
887da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
8884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
8901c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8911c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
8924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
8933d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
89499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
89599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
89699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
89799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
89899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
89999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
9004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
9014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
90299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
90399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
904351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
905db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
906351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
907db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
908bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
9092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
9102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
9112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
9122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
9132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
9142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
9152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
9162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
9172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
919db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    const IGraphicBufferConsumer::BufferItem& item) {
9202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
9212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
9222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
9252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
9262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
9282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
9292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
9302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
9312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
9342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
9352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
9372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
9382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
9392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
9402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
9412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
9422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
9432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
9442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
9462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
9472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
9482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
9492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
9502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
9512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
9522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
9542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
9552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
9562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
9586905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
9592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
9602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
9616905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
9622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
9632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
9642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
9652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
9662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
9672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
9682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
9692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
9702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
9712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
9722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
9732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
9742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
9752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
9762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
9792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
9802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
9814824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
9822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
9832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
9842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9852ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
9862ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
9872ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
9882ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
9892ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
9902ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
9912ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
9922ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
9936c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
9946c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
9956c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
9966c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
9976c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
9986c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
9996c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
10006c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
10016c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10026c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
10032ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
10042ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
10052ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
10072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
10092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
10122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10131585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
10141585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
10151585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
10161585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
10171585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
10181585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
10191585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
10201585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
10211585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
10221585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
10231585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
10241585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
10251585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
10261585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
10271585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1028a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1029a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
10304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1031a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1032d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1033351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1034bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1035e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1036e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1038e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1039da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
10404824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1041702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1042e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
10432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
10442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1045ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
10462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1047702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1048bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1049bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1050bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1051702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1052702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1053702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1054702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1055702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1056702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1057702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1058ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1059702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1060702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1061702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1062e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1063e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1064702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1065702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1066ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1067702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1068702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1069702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1070702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1071702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
1072702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1073702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1074702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
10754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
10761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(getDrawingState());
10771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
10781c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
10794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
10801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
108513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
108613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
108713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
108813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
108913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
109013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
109113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
109213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
109313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
109413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
109513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
109613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
109713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
109813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
109913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
110013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
110113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
110213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
110313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
110413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
110513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
110613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
110713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
110813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
110913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
111013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
111113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
111213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
111313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
111413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11153e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
11161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
11171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
111813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
112074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
112213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
11233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
112413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11252ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
112613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
112713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
112813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
112974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
113013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
113213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
113313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
113413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
113513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
113613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
113713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            isOpaque(), contentDirty,
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
114113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
11421b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1143a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1144a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
11451b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
11461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
11471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
11481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
11501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
115174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
11521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1153ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
11546905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
11566905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
11571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1158bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
115974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1160bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1161d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1162d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
116374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid Layer::dumpStats(String8& result) const {
116482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
116582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
116682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearStats() {
116882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
116925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
117025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
11716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
11726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
11736547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
11746547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
117713127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
117913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1180b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1181b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
118213127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
118313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1185a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1186a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
11883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
11913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
11923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
11953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
11963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1197