Layer.cpp revision 4125a4ffaf374ca9c0773f256998557d3325343e
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        mTransactionFlags(0),
68a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
70933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
724d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
765cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
77b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mClientRef(client)
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
8449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
884125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
904125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1126547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
114e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
115e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
117bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
118db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mBufferQueue = new SurfaceTextureLayer(mFlinger);
1193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
120bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
121bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
1224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
123b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1247f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1257f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1277f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
128bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
129303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1306905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
133b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
13496f0819f81293076e652792794a961543e6750d7Mathias Agopian
1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
13613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
13713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
13813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
13913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
140921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
14396f0819f81293076e652792794a961543e6750d7Mathias Agopian
14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
14613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
14713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
14813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
14913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
15213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
15413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
156a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1573d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
15899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
159579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
160579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1616710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1626710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1636710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
16413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
16648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
167cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
16813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
16913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
17013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
17113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
17313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
17413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
17513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
17613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
17713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
18013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
18113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
18313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
18413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
18513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
18613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
18713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
18813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
18913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
19013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
19313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
19413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
20013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
210882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
214882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
217882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
220a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
221a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
225a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
228582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
229582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
230db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopiansp<IGraphicBufferProducer> Layer::getBufferQueue() const {
231db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    return mBufferQueue;
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
23513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
23613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
23713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
238a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
239a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
240a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
241f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
243a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
244f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
245a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
246a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
247a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
248f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
249a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
251f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
252f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
253f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
254f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
255f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
256f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
257f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
258f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
259f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
260f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
261f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
262f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
263f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
264f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
26513127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
26713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
26813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
26913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
27013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
2716c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
272f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return reduce(win, s.activeTransparentRegion);
27313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
27413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2756b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
27613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
27713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
2786b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
27913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
28113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
2821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
28313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
28413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
28513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
2866b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
2876b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
2886b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
2896b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
2900e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
2910e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
2920e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
2930e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
2940e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
2950e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
2960e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
29713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
29813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
29913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
30013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // paranoia: make sure the window-crop is constrained in the
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // window's bounds
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
304f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
305f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
306f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
30913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3116b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
31213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
31613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
31813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
32013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
32113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                invTransform, s.active.w, s.active.h);
32213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3246b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3256b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
32613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3276b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetL = winCrop.left                 * xScale;
3286b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetT = winCrop.top                  * yScale;
3296b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetR = (winWidth  - winCrop.right ) * xScale;
3306b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float insetB = (winHeight - winCrop.bottom) * yScale;
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
33413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
33513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
33613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
33713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
33813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
33913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
3414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
3424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
343a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
34413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
345a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
3463e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
3473e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
348a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
349dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
350dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
351dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
352dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
35313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
3541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
3554125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
35613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
35713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
35813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
35913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
36013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
36113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
36213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
36313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect frame(s.transform.transform(computeBounds()));
36413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
36513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
36613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
36713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
3689f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
3699f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
37029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
37129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
37229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
37329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
37429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
37529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
37629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
37729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
37829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
379c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
380c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
381c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
382c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
383c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
384c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
385c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
386c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
387c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
388c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
389c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
390c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
391c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
392c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        transform = transform * Transform(invTransform);
393c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
39429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
39529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
39613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
39713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
39813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
3993e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
400a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
40113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
402a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
403a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
404a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
4054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
406d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
40913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
41013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
41113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
41213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
41413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
41513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4163e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
4173e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
41871e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    layer.setBuffer(mActiveBuffer);
419c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
420dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
4214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
422d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
423c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
424d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
425d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
426d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
427d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
428d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
429bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
4301df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
431c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
432dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
433dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
434dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
435dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
436dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
437c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
438c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
439c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
44013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
44113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
44213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
44313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
44413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
44513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    onDraw(hw, clip);
44613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
44713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
44813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw) {
44913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    onDraw( hw, Region(hw->bounds()) );
45013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
45113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4541c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
456a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
458179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
459179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
460179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
461179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
462179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
463179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
464179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
465179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
466179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
467f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
468f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
469179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
470179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
47113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
47213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
473179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
4744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
475179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
476179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
477179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
478179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
4791b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
480179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
483a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
48497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
48597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
486bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
487bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
48897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
489dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
490dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
491dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
492dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
493dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
494dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
495875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
496875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
497dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
498cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
499eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
500cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
501cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
502cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
503bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
504bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
505cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
506c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
507c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
508c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
509c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
510c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
511c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
512c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
513c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
514c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
515c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
516c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
517c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
518c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
519c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
520c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
521c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
522c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
523c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
524c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
525c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
526c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
527c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
528c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
529c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
530c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
531c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
532c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
533c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
534cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
53549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
53649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
53749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
53849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
53949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
540a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
541875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
542a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
5431b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
544875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
54813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
5493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        float red, float green, float blue, float alpha) const
55013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
55119733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
5525cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    computeGeometry(hw, mMesh);
55319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
55419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
55513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
55613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
55713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
55813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
55913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
56013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
56113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
56213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::drawWithOpenGL(
56313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
56413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t fbHeight = hw->getHeight();
5651eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
56613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
5675cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    computeGeometry(hw, mMesh);
56813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
56913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
57013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
57113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
57213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
57313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
57413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
57513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
57613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
57713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
578c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
57913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
58013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
58113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
58213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
58313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
58413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
5853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
5863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
5873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
5883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
58913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
590875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
591875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
592ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
593ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
594ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
595ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
596ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
59713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
598875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
5994125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
6005cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
601875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
60213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
60313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
60413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
60513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
60613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
60713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
60813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
60913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
61013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
61113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
612ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
613ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
614ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
615ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
616ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
617ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
618ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6195773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
620a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
621a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
622ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
6235773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
6245773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
6255773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
626c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        case HAL_PIXEL_FORMAT_sRGB_A_8888:
627dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
6285773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
6295773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
630dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
631ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
632ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
63313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
63413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
63513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
63613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
6373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
63813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
6391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
64013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform tr(hw->getTransform() * s.transform);
64113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
64213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
64313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
64413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
64513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
6466c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
647f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
6483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
649ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
650ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
651ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
652ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
653ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
6543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
6555cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
65613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
65713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
658ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
6594125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
660a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
661a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
662a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
663db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
664a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
665db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
666a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
667a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
668a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
6694125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
670a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
671a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
6727a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
6737a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
674a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
6757a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
6767a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
6777a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
678b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
67913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
68013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
68113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
68213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
68313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
68413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
68513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
68613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
68713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
68813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
68913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
69013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
69113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
69213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
69313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
69413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
69513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
69613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
69713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
69813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
69913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
70213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
70313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
70413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
70513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
70813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
70913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
71013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
71113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
7121c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
7131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
7151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
7181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
719a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
720a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
721cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
7229d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
7236905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
724419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
725419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
726419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
727419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
7281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
7291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
7301eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
7311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
7321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
7331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
7341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
7351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
7361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
7371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
7381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
7391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
7401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
7411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
7421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
7431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
7441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
7451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
7461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
7471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
7481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
7491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
7501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
7511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
7521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
7531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
7541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
7551eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
7561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
757a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
7582a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
7592a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
760bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
7611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
763cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
7640cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
7650cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
7671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
7680cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7690cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
77013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
7710cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
7720cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
7730cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
7740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
7750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
7760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
7770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
7780cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
7790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
7800cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
7810cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
7820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
78413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
78513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
7871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
7881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
79013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
79213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
79813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
79913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
80013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
80113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
8021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
8031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
80413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
80513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
80613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
80713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
80913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
81313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
814a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
815a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
81613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
81713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
81813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
81913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
82113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
82213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
82313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
82413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
82513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
82613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
82713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
82813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
82913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
83013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
85913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
86013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
8642ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
86513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
86613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
86713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
86813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
86913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
87013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
87113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
87213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
87313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
87413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
87513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
87613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
87713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
87813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
87913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
88013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
88113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
88213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
88313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
88413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
88513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
88613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
88713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
88813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
88913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
89013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
89113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
89213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
893a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
894a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
9004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
9014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
90299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
90399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
904d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
905d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
906bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
90782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
90882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
909bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
910789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
91182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
91282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
91382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
91482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
91582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
91682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
91782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
918d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
91982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
920789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
92182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
92282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
92382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
92482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
92582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
92682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
92782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
92882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
92982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
930d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
931d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
932d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
933d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
934da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
93513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
93613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
93713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            && (mActiveBuffer != NULL);
938da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
939da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
9404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9421c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
9431c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
9444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
9453d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
94699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
94799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
94899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
94999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
95099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
95199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
9524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
9534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
95499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
95599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
956351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
9574125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
9584125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
959351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
960db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
961bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
9622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
9632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
9642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
9652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
9662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
9672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
9682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
9692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
9702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
972db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    const IGraphicBufferConsumer::BufferItem& item) {
9732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
9742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
9752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
9782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
9792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
9812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
9822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
9832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
9842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
9852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
9872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
9882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
9902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
9912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
9922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
9932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
9942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
9952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
9962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
9972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
9982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
9992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
10002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
10012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
10022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
10032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
10042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
10052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
10072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
10082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
10116905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
10122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
10132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
10146905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
10152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
10162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
10172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
10182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
10192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
10202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
10212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
10222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
10232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
10242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
10252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
10262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
10272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
10282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
10292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
10322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
10332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
10344824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
10354ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian                        //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
10364ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian                        //        bufWidth, bufHeight, front.active.w, front.active.h);
10372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
10382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
10392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
10402ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10412ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
10422ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
10432ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
10442ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
10452ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
10462ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
10472ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
10486c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10496c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
10506c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
10516c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
10526c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
10536c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
10546c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
10556c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
10566c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
10576c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
10582ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
10592ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
10602ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
10612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
10622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
10632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
10642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
10672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
10681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
10691585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
10701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
10711585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
10721585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
10731585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
10741585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
10751585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
10761585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
10771585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
10781585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
10791585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
10801585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
10811585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
10821585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1083a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1084a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
10854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1086a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1087d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1088351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1089bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1090e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1091e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
10924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1093e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1094da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
10954824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1096702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1097e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
10982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
10992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1100ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
11012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1102702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1103bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1104bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1105bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1106702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1107702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1108702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1109702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1110702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1111702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1112702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1113ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1114702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1115702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1116702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1117e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1118e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1119702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1120702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1121ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1122702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1123702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1124702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1125702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
11264125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1127702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1128702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1129702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
11304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
11311eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
11321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
11334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
11341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
113913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
114013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
114113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
114213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
114313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
114413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
114513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
114613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
114713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
114813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
114913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
115013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
115113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
115213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
115313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
115413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
115513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
115613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
115713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
115813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
115913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
116013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
116113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
116213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
116313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
116513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
116713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
116813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
11701b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
11711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
117213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
117474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
117513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
11773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
117813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
11792ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
118013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
118113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
118213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
118374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
118413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
118513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
118613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
118713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
118913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
119013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
11914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
119213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
119313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
119413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
119513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
11961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1197a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1198a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
11991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
12001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
12011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
12021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1203a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
12041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
120574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
12061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1207ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
12086905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1209a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
12106905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
12111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1212bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
121374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1214bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1215d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1216d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
121774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid Layer::dumpStats(String8& result) const {
121882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
121982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
122082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
122113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearStats() {
122282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
122325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
122425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
12256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
12266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
12276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
12286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
122913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
123013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
123113127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
123213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
123313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1234b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1235b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
123613127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
123713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
123813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1239a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1240a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
12423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
12453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
12463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
12493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
12503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1251