Layer.cpp revision 9e9b0445544f11fdbf21a29601567af2d1819a30
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>
30399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall#include <utils/NativeHandle.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
369cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza#include <gui/BufferItem.h>
3890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
420f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
44b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza#include "MonitoredProducer.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
49875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
50875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianint32_t Layer::sSequence = 1;
5813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
6113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    :   contentDirty(false),
6213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sequence(uint32_t(android_atomic_inc(&sSequence))),
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFlinger(flinger),
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
6513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mPremultipliedAlpha(true),
6613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mName("unnamed"),
6713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
6813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mTransactionFlags(0),
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
70399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStreamChanged(false),
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
72933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
73a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
7582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
7613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mFiltering(false),
7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mNeedsFiltering(false),
785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
79b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
8013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mProtectedByApp(false),
8113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        mHasSurface(false),
8203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mClientRef(client),
8303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        mPotentialCursor(false)
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
85a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
8749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    uint32_t layerFlags = 0;
904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eHidden)
914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerHidden;
924125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (flags & ISurfaceComposerClient::eOpaque)
934125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        layerFlags |= layer_state_t::eLayerOpaque;
944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (flags & ISurfaceComposerClient::eNonPremultiplied)
964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        mPremultipliedAlpha = false;
974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mName = name;
994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.w = w;
1014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.h = h;
1024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.active.crop.makeInvalid();
1034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.z = 0;
1044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.alpha = 0xFF;
1054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.layerStack = 0;
1064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.flags = layerFlags;
1074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.sequence = 0;
1084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.transform.set(0, 0);
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mCurrentState.requested = mCurrentState.active;
1104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    // drawing state & current state are identical
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mDrawingState = mCurrentState;
1136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    nsecs_t displayPeriod =
1156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
1166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
117e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
118e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid Layer::onFirstRef() {
120bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
121b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferProducer> producer;
122b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza    sp<IGraphicBufferConsumer> consumer;
123b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
124b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mProducer = new MonitoredProducer(producer, mFlinger);
125b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
127399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    mSurfaceFlingerConsumer->setContentsChangedListener(this);
1284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mSurfaceFlingerConsumer->setName(mName);
129b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1307f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1317f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
132bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
1337f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
134bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
135303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
1366905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
139b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
14096f0819f81293076e652792794a961543e6750d7Mathias Agopian
1414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias AgopianLayer::~Layer() {
14213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> c(mClientRef.promote());
14313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (c != 0) {
14413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        c->detachLayer(this);
14513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
146921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
1476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
14996f0819f81293076e652792794a961543e6750d7Mathias Agopian
15013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// callbacks
15213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
15313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
154c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
15513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        HWComposer::HWCLayerInterface* layer) {
15613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (layer) {
15713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer->onDisplayed();
15813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
15913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
16013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
16113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1626b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameAvailable(const BufferItem& item) {
1636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Add this buffer from our internal queue tracker
1646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    { // Autolock scope
1656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        Mutex::Autolock lock(mQueueItemLock);
1666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        mQueueItems.push_back(item);
1676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
1686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
1693d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
17099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
171579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
172579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
1736b9454d1fee0347711af1746642aa7820b1ea04dDan Stozavoid Layer::onFrameReplaced(const BufferItem& item) {
1746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
1756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    if (mQueueItems.empty()) {
1766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        ALOGE("Can't replace a frame on an empty queue");
1776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return;
1786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
1796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    mQueueItems.editItemAt(0) = item;
1806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
1816b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
182399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hallvoid Layer::onSidebandStreamChanged() {
183399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
184399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was false
185399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mFlinger->signalLayerUpdate();
186399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
187399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall}
188399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
1896710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// called with SurfaceFlinger::mStateLock from the drawing thread after
1906710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// the layer has been remove from the current state list (and just before
1916710604286401d4205c27235a252dd0e5008cc08Mathias Agopian// it's removed from the drawing state list)
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::onRemoved() {
193bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
19448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
195cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
19613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// set-up
19813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
19913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopianconst String8& Layer::getName() const {
20113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mName;
20213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
20313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
20413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
20513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            PixelFormat format, uint32_t flags)
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t const maxSurfaceDims = min(
20813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
20913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // never allow a surface larger than what our underlying GL implementation
21113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // can handle.
21213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
21313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
21413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return BAD_VALUE;
21513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
21613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFormat = format;
21813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
21903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
22013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
22113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
22213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
22313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
22513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
22613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
22713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
22813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return NO_ERROR;
22913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
23013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
2314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopiansp<IBinder> Layer::getHandle() {
2324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    Mutex::Autolock _l(mLock);
2334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    LOG_ALWAYS_FATAL_IF(mHasSurface,
2354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            "Layer::getHandle() has already been called");
2364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    mHasSurface = true;
2384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
239882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
2404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * The layer handle is just a BBinder object passed to the client
2414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * (remote process) -- we don't keep any reference on our side such that
2424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * the dtor is called when the remote side let go of its reference.
243882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
2444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
2454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian     * this layer when the handle is destroyed.
246882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
2474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    class Handle : public BBinder, public LayerCleaner {
249a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
250a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
2514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
2524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) {
2534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        }
254a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return new Handle(mFlinger, this);
257582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
258582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
259b9b088375d33a87b201cdbe18be71802e2607717Dan Stozasp<IGraphicBufferProducer> Layer::getProducer() const {
260b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    return mProducer;
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
26413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// h/w composer set-up
26513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
26613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
267a8bca8d84b559e7dcca010f7d6514333004020c7Mathias AgopianRect Layer::getContentCrop() const {
268a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // this is the crop rectangle that applies to the buffer
269a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    // itself (as opposed to the window)
270f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
271f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
272a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if the buffer crop is defined, we use that
273f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
274a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian    } else if (mActiveBuffer != NULL) {
275a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // otherwise we use the whole buffer
276a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        crop = mActiveBuffer->getBounds();
277f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
278a8bca8d84b559e7dcca010f7d6514333004020c7Mathias Agopian        // if we don't have a buffer yet, we use an empty/invalid crop
2794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
280f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
281f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
282f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
283f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
284f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopianstatic Rect reduce(const Rect& win, const Region& exclude) {
285f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (CC_LIKELY(exclude.isEmpty())) {
286f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win;
287f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
288f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    if (exclude.isRect()) {
289f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian        return win.reduce(exclude.getBounds());
290f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    }
291f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    return Region(win).subtract(exclude).getBounds();
292f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian}
293f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
29413127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianRect Layer::computeBounds() const {
2951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
2966c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return computeBounds(s.activeTransparentRegion);
2976c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine}
2986c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine
2996c925ede620f4080227bb1fe8a41e4b4502348f8Michael LentineRect Layer::computeBounds(const Region& activeTransparentRegion) const {
3006c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    const Layer::State& s(getDrawingState());
30113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
30213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
30413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
3056c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
3066c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    return reduce(win, activeTransparentRegion);
30713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3096b44267a3beb457e220cad0666c039d3a765cdb2Mathias AgopianFloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
31013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the content crop is the area of the content that gets scaled to the
31113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layer's size.
3126b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    FloatRect crop(getContentCrop());
31313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // the active.crop is the area of the window that gets cropped, but not
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // scaled in any ways.
3161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
31713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
31813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the projection's clipping to the window crop in
31913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // layerstack space, and convert-back to layer space.
3206b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // if there are no window scaling involved, this operation will map to full
3216b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // pixels in the buffer.
3226b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
3236b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian    // a viewport clipping and a window transform. we should use floating point to fix this.
3240e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3250e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    Rect activeCrop(s.active.w, s.active.h);
3260e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    if (!s.active.crop.isEmpty()) {
3270e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian        activeCrop = s.active.crop;
3280e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    }
3290e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian
3300e8f1443b87f9009159cef6394de48894f98f826Mathias Agopian    activeCrop = s.transform.transform(activeCrop);
33113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(hw->getViewport(), &activeCrop);
33213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop = s.transform.inverse().transform(activeCrop);
33313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
33428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // This needs to be here as transform.transform(Rect) computes the
33528ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transformed rect and then takes the bounding box of the result before
33628ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // returning. This means
33728ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // transform.inverse().transform(transform.transform(Rect)) != Rect
33828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // in which case we need to make sure the final rect is clipped to the
33928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine    // display bounds.
34013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
34113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
342f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // subtract the transparent region and snap to the bounds
343f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    activeCrop = reduce(activeCrop, s.activeTransparentRegion);
344f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
34513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!activeCrop.isEmpty()) {
34613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // Transform the window crop to match the buffer coordinate system,
34713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // which means using the inverse of the current transform set on the
34813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // SurfaceFlingerConsumer.
3496b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        uint32_t invTransform = mCurrentTransform;
350f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
351f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            /*
352f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             * the code below applies the display's inverse transform to the buffer
353f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine             */
354f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            uint32_t invTransformOrient = hw->getOrientationTransform();
355f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // calculate the inverse transform
356f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
357f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
358f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
3591440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // If the transform has been rotated the axis of flip has been swapped
3601440963470cda68be762957e2efb7ecbe1570366Michael Lentine                // so we need to swap which flip operations we are performing
3611440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
3621440963470cda68be762957e2efb7ecbe1570366Michael Lentine                bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
3631440963470cda68be762957e2efb7ecbe1570366Michael Lentine                if (is_h_flipped != is_v_flipped) {
3641440963470cda68be762957e2efb7ecbe1570366Michael Lentine                    invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
3651440963470cda68be762957e2efb7ecbe1570366Michael Lentine                            NATIVE_WINDOW_TRANSFORM_FLIP_H;
3661440963470cda68be762957e2efb7ecbe1570366Michael Lentine                }
367f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            }
368f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            // and apply to the current transform
369f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine            invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation();
370f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        }
371f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine
37213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winWidth = s.active.w;
37313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        int winHeight = s.active.h;
37413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
3757b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // If the activeCrop has been rotate the ends are rotated but not
3767b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // the space itself so when transforming ends back we can't rely on
3777b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // a modification of the axes of rotation. To account for this we
3787b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // need to reorient the inverse rotation in terms of the current
3797b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            // axes of rotation.
3807b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
3817b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
3827b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            if (is_h_flipped == is_v_flipped) {
3837b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
3847b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
3857b90258c7b1b6caf7fbbf62423723d0f4cdc79aaMichael Lentine            }
38613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winWidth = s.active.h;
38713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            winHeight = s.active.w;
38813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
38913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Rect winCrop = activeCrop.transform(
390f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine                invTransform, s.active.w, s.active.h);
39113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
3926b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        // below, crop is intersected with winCrop expressed in crop's coordinate space
3936b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float xScale = crop.getWidth()  / float(winWidth);
3946b44267a3beb457e220cad0666c039d3a765cdb2Mathias Agopian        float yScale = crop.getHeight() / float(winHeight);
39513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
396f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetL = winCrop.left                 * xScale;
397f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetT = winCrop.top                  * yScale;
398f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetR = (winWidth - winCrop.right )  * xScale;
399f75514079434cefcdb746e8b083708d6de5f86ffMichael Lentine        float insetB = (winHeight - winCrop.bottom) * yScale;
40013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
40113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.left   += insetL;
40213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.top    += insetT;
40313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.right  -= insetR;
40413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        crop.bottom -= insetB;
40513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
40613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return crop;
40713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
40813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
4094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
4104297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
4114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
412a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
41313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setDefaultState();
414a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
4153e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
4163e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
417a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
418dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
419dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
420dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
421dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
42213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this gives us only the "orientation" component of the transform
4231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
4244125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    if (!isOpaque(s) || s.alpha != 0xFF) {
42513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setBlending(mPremultipliedAlpha ?
42613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_PREMULT :
42713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                HWC_BLENDING_COVERAGE);
42813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
42913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
43013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // apply the layer's transform, followed by the display's global transform
43113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // here we're guaranteed that the layer's transform preserves rects
4326c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Region activeTransparentRegion(s.activeTransparentRegion);
4336c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    if (!s.active.crop.isEmpty()) {
4346c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        Rect activeCrop(s.active.crop);
4356c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.transform(activeCrop);
4366c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop.intersect(hw->getViewport(), &activeCrop);
4376c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeCrop = s.transform.inverse().transform(activeCrop);
43828ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // This needs to be here as transform.transform(Rect) computes the
43928ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transformed rect and then takes the bounding box of the result before
44028ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // returning. This means
44128ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // transform.inverse().transform(transform.transform(Rect)) != Rect
44228ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // in which case we need to make sure the final rect is clipped to the
44328ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        // display bounds.
44428ea217ff4e0aa9b03dfc12b6f47cccc6aaaae08Michael Lentine        activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
4456c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        // mark regions outside the crop as transparent
4466c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
4476c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
4486c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, s.active.h));
4496c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
4506c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                activeCrop.left, activeCrop.bottom));
4516c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
4526c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine                s.active.w, activeCrop.bottom));
4536c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    }
4546c925ede620f4080227bb1fe8a41e4b4502348f8Michael Lentine    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
45513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    frame.intersect(hw->getViewport(), &frame);
45613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr(hw->getTransform());
45713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setFrame(tr.transform(frame));
45813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setCrop(computeCrop(hw));
4599f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian    layer.setPlaneAlpha(s.alpha);
4609f8386e1118c10dd4927f62637ec7162569bdbdcMathias Agopian
46129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
46229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
46329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
46429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
46529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
46629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
46729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
46829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
46929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
470c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    Transform transform(tr * s.transform * bufferOrientation);
471c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
472c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
473c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        /*
474c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         * the code below applies the display's inverse transform to the buffer
475c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian         */
476c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        uint32_t invTransform = hw->getOrientationTransform();
4771440963470cda68be762957e2efb7ecbe1570366Michael Lentine        uint32_t t_orientation = transform.getOrientation();
478c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // calculate the inverse transform
479c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
480c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
481c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
4821440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // If the transform has been rotated the axis of flip has been swapped
4831440963470cda68be762957e2efb7ecbe1570366Michael Lentine            // so we need to swap which flip operations we are performing
4841440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
4851440963470cda68be762957e2efb7ecbe1570366Michael Lentine            bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
4861440963470cda68be762957e2efb7ecbe1570366Michael Lentine            if (is_h_flipped != is_v_flipped) {
4871440963470cda68be762957e2efb7ecbe1570366Michael Lentine                t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
4881440963470cda68be762957e2efb7ecbe1570366Michael Lentine                        NATIVE_WINDOW_TRANSFORM_FLIP_H;
4891440963470cda68be762957e2efb7ecbe1570366Michael Lentine            }
490c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
491c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        // and apply to the current transform
4921440963470cda68be762957e2efb7ecbe1570366Michael Lentine        transform = Transform(t_orientation) * Transform(invTransform);
493c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
49429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
49529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
49613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t orientation = transform.getOrientation();
49713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (orientation & Transform::ROT_INVALID) {
49813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we can only handle simple transformation
4993e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
500a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
50113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        layer.setTransform(orientation);
502a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
503a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
504a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
5054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
506d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
50713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we have to set the visible region on every frame because
50813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // we currently free it during onLayerDisplayed(), which is called
50913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // after HWComposer::commit() -- every frame.
51013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Apply this display's projection's viewport to the visible region
51113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // before giving it to the HWC HAL.
51213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Transform& tr = hw->getTransform();
51313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
51413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    layer.setVisibleRegionScreen(visible);
51513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
516ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    // Pass full-surface damage down untouched
517ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (surfaceDamageRegion.isRect() &&
518ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
519ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer.setSurfaceDamage(surfaceDamageRegion);
520ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
521ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        Region surfaceDamage =
522ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
523ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer.setSurfaceDamage(surfaceDamage);
524ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
525ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
526399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (mSidebandStream.get()) {
527399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setSidebandStream(mSidebandStream);
528399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    } else {
529399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // NOTE: buffer can be NULL if the client never drew into this
530399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // layer yet, or if we ran out of memory
531399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        layer.setBuffer(mActiveBuffer);
532399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
533c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
534dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
535c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
536d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
537c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
538d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
539d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
540d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
541d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
54203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
543bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
5441df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        if (fence->isValid()) {
545c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
546dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
547dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
548dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
549dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
550dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
551c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
552c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
553c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
55403414a1cfe6c1222fd7723949bd622f9cba145aaRiley AndrewsRect Layer::getPosition(
55503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const sp<const DisplayDevice>& hw)
55603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
55703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // this gives us only the "orientation" component of the transform
55803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const State& s(getCurrentState());
55903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
56003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // apply the layer's transform, followed by the display's global transform
56103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // here we're guaranteed that the layer's transform preserves rects
56203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect win(s.active.w, s.active.h);
56303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (!s.active.crop.isEmpty()) {
56403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        win.intersect(s.active.crop, &win);
56503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
56603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    // subtract the transparent region and snap to the bounds
56703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect bounds = reduce(win, s.activeTransparentRegion);
56803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    Rect frame(s.transform.transform(bounds));
56903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    frame.intersect(hw->getViewport(), &frame);
57003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    const Transform& tr(hw->getTransform());
57103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    return Rect(tr.transform(frame));
57203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
57303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
57413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
57513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// drawing...
57613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
57713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
57813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
579c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, clip, false);
58013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
58113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
582c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw,
583c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const {
584c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
58513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
58613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
587c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::draw(const sp<const DisplayDevice>& hw) const {
588c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    onDraw(hw, Region(hw->bounds()), false);
589c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza}
590c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza
591c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
592c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5941c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5951c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
596a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
598179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
599179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
600179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
601179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
602179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
603179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
604179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
605179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
606179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
607f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
608f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
609179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
610179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
61113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(drawingLayers[i]);
61213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            if (layer.get() == static_cast<Layer const*>(this))
613179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
6144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
615179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
616179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
617179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
618179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
6191b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
620179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
623a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
62497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
62597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
626bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
627bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
62897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
629dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
630dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
631dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
632dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
633dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
634dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
635875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
636875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
637dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
638cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
639eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
640cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
641cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
642cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
643bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
644bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
645cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
646c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
647c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
648c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            /*
649c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             * the code below applies the display's inverse transform to the texture transform
650c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian             */
651c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
652c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // create a 4x4 transform matrix from the display transform flags
653c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
654c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
655c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
656c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
657c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            mat4 tr;
658c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            uint32_t transform = hw->getOrientationTransform();
659c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
660c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * rot90;
661c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
662c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipH;
663c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
664c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian                tr = tr * flipV;
665c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
666c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // calculate the inverse
667c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            tr = inverse(tr);
668c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
669c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            // and finally apply it to the original texture matrix
670c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
671c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
672c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        }
673c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
674cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
67549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
67649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setFiltering(useFiltering);
67749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        mTexture.setMatrix(textureMatrix);
67849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian
67949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian        engine.setupLayerTexturing(mTexture);
680a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
681875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        engine.setupLayerBlackedOut();
682a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
683c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    drawWithOpenGL(hw, clip, useIdentityTransform);
684875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableTexturing();
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
688c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
689c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, float red, float green, float blue,
690c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        float alpha) const
69113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
69219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
693c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, false);
69419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.setupFillWithColor(red, green, blue, alpha);
69519733a32799f792125913e746e8644d16f8dc223Mathias Agopian    engine.drawMesh(mMesh);
69613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
69713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
69813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::clearWithOpenGL(
69913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<const DisplayDevice>& hw, const Region& clip) const {
70013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    clearWithOpenGL(hw, clip, 0,0,0,0);
70113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
70213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
703c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
704c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        const Region& /* clip */, bool useIdentityTransform) const {
7051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const State& s(getDrawingState());
70613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
707c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    computeGeometry(hw, mMesh, useIdentityTransform);
70813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
70913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    /*
71013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * NOTE: the way we compute the texture coordinates here produces
71113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * different results than when we take the HWC path -- in the later case
71213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * the "source crop" is rounded to texel boundaries.
71313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * This can produce significantly different results when the texture
71413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * is scaled by a large amount.
71513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     *
71613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * The GL code below is more logical (imho), and the difference with
71713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * HWC is due to a limitation of the HWC API to integers -- a question
718c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian     * is suspend is whether we should ignore this problem or revert to
71913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * GL composition when a buffer scaling is applied (maybe with some
72013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * minimal value)? Or, we could make GL behave like HWC -- but this feel
72113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     * like more of a hack.
72213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian     */
72313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Rect win(computeBounds());
72413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float left   = float(win.left)   / float(s.active.w);
7263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float top    = float(win.top)    / float(s.active.h);
7273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float right  = float(win.right)  / float(s.active.w);
7283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    float bottom = float(win.bottom) / float(s.active.h);
72913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
730875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // TODO: we probably want to generate the texture coords with the mesh
731875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // here we assume that we only have 4 vertices
732ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
733ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[0] = vec2(left, 1.0f - top);
734ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[1] = vec2(left, 1.0f - bottom);
735ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[2] = vec2(right, 1.0f - bottom);
736ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoords[3] = vec2(right, 1.0f - top);
73713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
738875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    RenderEngine& engine(mFlinger->getRenderEngine());
7394125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
7405cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian    engine.drawMesh(mMesh);
741875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    engine.disableBlending();
74213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
74313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
7441681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunkuint32_t Layer::getProducerStickyTransform() const {
7451681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int producerStickyTransform = 0;
7461681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
7471681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    if (ret != OK) {
7481681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
7491681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                strerror(-ret), ret);
7501681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        return 0;
7511681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    }
7521681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk    return static_cast<uint32_t>(producerStickyTransform);
7531681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk}
7541681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk
75513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setFiltering(bool filtering) {
75613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFiltering = filtering;
75713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
75813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
75913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::getFiltering() const {
76013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mFiltering;
76113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
76213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
763ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
764ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
765ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
766ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
767ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
768ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
769ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
7705773d3f5b2694c647e010246dff99acc70131289Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format) {
771a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
772a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
773ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
7745773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    switch (format) {
7755773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_RGBA_8888:
7765773d3f5b2694c647e010246dff99acc70131289Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888:
777dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian            return false;
7785773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    }
7795773d3f5b2694c647e010246dff99acc70131289Mathias Agopian    // in all other case, we have no blending (also for unknown formats)
780dd533712f8dd21c0dadfd5ce8a0ad85aa3e96adaMathias Agopian    return true;
781ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
782ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
78313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
78413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// local state
78513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
78613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
787c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
788c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) const
78913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
7901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
791c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza    const Transform tr(useIdentityTransform ?
792c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            hw->getTransform() : hw->getTransform() * s.transform);
79313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t hw_h = hw->getHeight();
79413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    Rect win(s.active.w, s.active.h);
79513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!s.active.crop.isEmpty()) {
79613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        win.intersect(s.active.crop, &win);
79713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
7986c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // subtract the transparent region and snap to the bounds
799f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    win = reduce(win, s.activeTransparentRegion);
8003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
801ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
802ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = tr.transform(win.left,  win.top);
803ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = tr.transform(win.left,  win.bottom);
804ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = tr.transform(win.right, win.bottom);
805ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = tr.transform(win.right, win.top);
8063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    for (size_t i=0 ; i<4 ; i++) {
8075cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian        position[i].y = hw_h - position[i].y;
80813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
80913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
810ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
8114125a4ffaf374ca9c0773f256998557d3325343eAndy McFaddenbool Layer::isOpaque(const Layer::State& s) const
812a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
813a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
814a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
815db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
816a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
817db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
818a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
819a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
820a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
8214125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
822a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
823a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
8247a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
8257a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
826a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
8277a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
8287a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
8297a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
830b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
83113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isFixedSize() const {
83213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
83313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
83513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::isCropped() const {
83613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !mCurrentCrop.isEmpty();
83713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
83813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
83913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
84013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return mNeedsFiltering || hw->needsFiltering();
84113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleRegion(const Region& visibleRegion) {
84413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
84513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleRegion = visibleRegion;
84613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
84713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
84813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setCoveredRegion(const Region& coveredRegion) {
84913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
85013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->coveredRegion = coveredRegion;
85113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::setVisibleNonTransparentRegion(const Region&
85413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        setVisibleNonTransparentRegion) {
85513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always called from main thread
85613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
85713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
85813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
85913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
86013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// transaction
86113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
86213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
86313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::doTransaction(uint32_t flags) {
8641c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
8651c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
8661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
8671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& c(getCurrentState());
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const bool sizeChanged = (c.requested.w != s.requested.w) ||
8701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                             (c.requested.h != s.requested.h);
871a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
872a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
873cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
8749d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
8756905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
876419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
877419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
878419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
879419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
8801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                this, getName().string(), mCurrentTransform, mCurrentScalingMode,
8811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.w, c.active.h,
8821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.left,
8831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.top,
8841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.right,
8851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.bottom,
8861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getWidth(),
8871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.active.crop.getHeight(),
8881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h,
8891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.left,
8901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.top,
8911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.right,
8921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.bottom,
8931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getWidth(),
8941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.crop.getHeight(),
8951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.w, s.active.h,
8961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.left,
8971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.top,
8981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.right,
8991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.bottom,
9001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getWidth(),
9011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.active.crop.getHeight(),
9021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.w, s.requested.h,
9031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.left,
9041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.top,
9051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.right,
9061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.bottom,
9071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getWidth(),
9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                s.requested.crop.getHeight());
909a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
9102a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
9112a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
912bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
9131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                c.requested.w, c.requested.h);
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
915cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
9160cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
9170cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const bool resizePending = (c.requested.w != c.active.w) ||
9191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                                   (c.requested.h != c.active.h);
9200cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9219e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza        if (resizePending && mSidebandStream == NULL) {
92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            // don't let Layer::doTransaction update the drawing state
9230cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
9240cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
9250cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
9260cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
9270cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
9280cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
9290cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
9309e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            //
9319e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // If a sideband stream is attached, however, we want to skip this
9329e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // optimization so that transactions aren't missed when a buffer
9339e9b0445544f11fdbf21a29601567af2d1819a30Dan Stoza            // never arrives
9340cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
9350cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
9360cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
9370cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
9380cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
93913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // always set active to requested, unless we're asked not to
94013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // this is used by Layer, which special cases resizes.
94113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (flags & eDontUpdateGeometryState)  {
94213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    } else {
9431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Layer::State& editCurrentState(getCurrentState());
9441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        editCurrentState.active = c.requested;
94513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
94613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (s.active != c.active) {
94813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
94913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= Layer::eVisibleRegion;
95013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
95113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
9521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (c.sequence != s.sequence) {
95313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // invalidate and recompute the visible regions if needed
95413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        flags |= eVisibleRegion;
95513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        this->contentDirty = true;
95613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
95713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // we may use linear filtering, if the matrix scales us
9581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const uint8_t type = c.transform.getType();
9591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        mNeedsFiltering = (!c.transform.preserveRects() ||
96013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                (type >= Transform::SCALE));
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
96213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
96313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // Commit the transaction
96413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    commitTransaction();
96513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return flags;
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
96813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::commitTransaction() {
96913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mDrawingState = mCurrentState;
970a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
971a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
97213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getTransactionFlags(uint32_t flags) {
97313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_and(~flags, &mTransactionFlags) & flags;
97413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
97513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
97613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::setTransactionFlags(uint32_t flags) {
97713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return android_atomic_or(flags, &mTransactionFlags);
97813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
97913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
98013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setPosition(float x, float y) {
98113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
98213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
98313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
98413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(x, y);
98513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
98613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
98813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayer(uint32_t z) {
98913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.z == z)
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
99113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
99213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.z = z;
99313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
99413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
99513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setSize(uint32_t w, uint32_t h) {
99713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
99813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
99913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.w = w;
100013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.h = h;
100113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
100213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
100313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setAlpha(uint8_t alpha) {
100513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.alpha == alpha)
100613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
100713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
100813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.alpha = alpha;
100913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
101013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
101213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
101313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
101413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.transform.set(
101513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
101613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
101713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
101813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
101913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setTransparentRegionHint(const Region& transparent) {
10202ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    mCurrentState.requestedTransparentRegion = transparent;
102113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
102213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
102313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
102413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setFlags(uint8_t flags, uint8_t mask) {
102513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
102613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.flags == newFlags)
102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
102813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
102913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.flags = newFlags;
103013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
103113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
103213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
103313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setCrop(const Rect& crop) {
103413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.requested.crop == crop)
103513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
103613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.requested.crop = crop;
103813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
103913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
104013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
104113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
104213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianbool Layer::setLayerStack(uint32_t layerStack) {
104313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mCurrentState.layerStack == layerStack)
104413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        return false;
104513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.sequence++;
104613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mCurrentState.layerStack = layerStack;
104713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    setTransactionFlags(eTransactionNeeded);
104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return true;
1049a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
1050a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
1051ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useSurfaceDamage() {
1052ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    if (mFlinger->mForceFullDamage) {
1053ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = Region::INVALID_REGION;
1054ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    } else {
1055ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
1056ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    }
1057ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1058ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1059ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stozavoid Layer::useEmptyDamage() {
1060ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.clear();
1061ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza}
1062ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza
1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10676b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool Layer::shouldPresentNow(const DispSync& dispSync) const {
10686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    Mutex::Autolock lock(mQueueItemLock);
10696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    nsecs_t expectedPresent =
10706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
10716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return mQueueItems.empty() ?
10726b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            false : mQueueItems[0].mTimestamp < expectedPresent;
10736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza}
10746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
10754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
10764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
1077399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    return mQueuedFrames > 0 || mSidebandStreamChanged;
107899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
107999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1080d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
1081d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
1082bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
108382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
108482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1085bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
1086789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (frameReadyFence->isValid()) {
108782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
108882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
108982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
109082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
109182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
109282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
109382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
1094d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
109582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1096789a6c3f1dfe22a1ffea7f39b2098d7842cd1f30Jamie Gennis        if (presentFence->isValid()) {
109782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
109882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
109982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
110082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
110182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
110282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
110382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
110482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
110582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
1106d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
1107d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1108d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
1109d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1110da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
111113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Layer::State& s(mDrawingState);
111213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
1113afe3081e0e224a3d88da2e8f211e994f833cc6bbWonsik Kim            && (mActiveBuffer != NULL || mSidebandStream != NULL);
1114da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
1115da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
11164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
11191c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
1120399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
1121399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        // mSidebandStreamChanged was true
1122399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
11235bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        recomputeVisibleRegions = true;
11245bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall
11255bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        const State& s(getDrawingState());
11265bf786d8f00ff8eee64ebf330dac55e33a0f97b1Jesse Hall        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
1127399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall    }
1128399184a4cd728ea1421fb0bc1722274a29e38f4aJesse Hall
11294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
11303d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
113199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
113299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
113399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
113499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
113599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
113699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
11374d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
11384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
113999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
114099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1141351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
11424125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const State& s(getDrawingState());
11434125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        const bool oldOpacity = isOpaque(s);
1144351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
1145db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
1146bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
11472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
11482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
11492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
11501681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk            bool stickyTransformSet;
11512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
11521681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                    bool& recomputeVisibleRegions, bool stickySet)
11532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
11541681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  recomputeVisibleRegions(recomputeVisibleRegions),
11551681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                  stickyTransformSet(stickySet) {
11562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
11572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
115911611f9be590480d7ea27bf0153558573ddcded2Dan Stoza                    const BufferItem& item) {
11602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
11612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
11622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
11632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
11652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
11662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
11682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
11692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
11702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
11712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
11722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
11742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
11752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
11772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
11782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
11792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
11802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
11812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
11822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
11832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
11842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
11862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
11872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
11882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
11892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
11902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
11912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
11922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
11942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
11952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
11962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
11972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
11986905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
11992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
12002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
12016905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
12022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
12032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
12042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
12052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
12062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
12072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
12082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
12092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
12102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
12112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
12122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
12132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
12142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
12152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
12162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12181681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                if (!isFixedSize && !stickyTransformSet) {
12192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
12202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
12214824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
12221681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                        ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
12231681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                                bufWidth, bufHeight, front.active.w, front.active.h);
12242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
12252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
12262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
12272ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
12282ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // if the transparent region has changed (this test is
12292ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // conservative, but that's fine, worst case we're doing
12302ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // a bit of extra work), we latch the new one and we
12312ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                // trigger a visible-region recompute.
12322ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                if (!front.activeTransparentRegion.isTriviallyEqual(
12332ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        front.requestedTransparentRegion)) {
12342ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    front.activeTransparentRegion = front.requestedTransparentRegion;
12356c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
12366c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // We also need to update the current state so that
12376c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // we don't end-up overwriting the drawing state with
12386c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // this stale current state during the next transaction
12396c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    //
12406c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // NOTE: We don't need to hold the transaction lock here
12416c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // because State::active is only accessed from this thread.
12426c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    current.activeTransparentRegion = front.activeTransparentRegion;
12436c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian
12446c67f0fe457f758fc875e1178d8fd5258fd8f6dfMathias Agopian                    // recompute visible region
12452ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                    recomputeVisibleRegions = true;
12462ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                }
12472ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian
12482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
12492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
12502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
12512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
12521681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk        Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
12531681d95989271f3a9ac0dbb93d10e4a29f2b4444Ruben Brunk                getProducerStickyTransform() != 0);
12542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
125541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
125641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden                mFlinger->mPrimaryDispSync);
12571585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult == BufferQueue::PRESENT_LATER) {
12581585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // Producer doesn't want buffer to be displayed yet.  Signal a
12591585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            // layer update so we check again at the next opportunity.
12601585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
12611585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            return outDirtyRegion;
12621585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
12631585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
12646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        // Remove this buffer from our internal queue tracker
12656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        { // Autolock scope
12666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            Mutex::Autolock lock(mQueueItemLock);
12676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            mQueueItems.removeAt(0);
12686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
12696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
12701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // Decrement the queued-frames count.  Signal another event if we
12711585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        // have more frames pending.
12721585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (android_atomic_dec(&mQueuedFrames) > 1) {
12731585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden            mFlinger->signalLayerUpdate();
12741585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        }
12751585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden
12761585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden        if (updateResult != NO_ERROR) {
1277a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
1278a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
12794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1280a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
1281d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
1282351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
1283bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1284e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
1285e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
12864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
1287e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
1288da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
12894824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
1290702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
1291e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
12922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
12932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
1294ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
12952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
1296702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1297bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1298bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1299bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1300702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
1301702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
1302702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
1303702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
1304702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
1305702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
1306702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
1307ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
1308702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1309702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1310702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
1311e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
1312e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
1313702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1314702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
1315ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
1316702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
1317702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1318702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
1319702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
13204125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if (oldOpacity != isOpaque(s)) {
1321702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
1322702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
1323702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
13244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
13251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        Region dirtyRegion(Rect(s.active.w, s.active.h));
13261c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
13274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
13281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        outDirtyRegion = (s.transform.transform(dirtyRegion));
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
133313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
133413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian{
133513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // TODO: should we do something special if mSecure is set?
133613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (mProtectedByApp) {
133713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // need a hardware-protected path to external video sink
133813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
133913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
134003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    if (mPotentialCursor) {
134103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        usage |= GraphicBuffer::USAGE_CURSOR;
134203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
134313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
134413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    return usage;
134513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
134613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
134713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
134813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    uint32_t orientation = 0;
134913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
135013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // The transform hint is used to improve performance, but we can
135113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // only have a single transform hint, it cannot
135213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        // apply to all displays.
135313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Transform& planeTransform(hw->getTransform());
135413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        orientation = planeTransform.getOrientation();
135513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        if (orientation & Transform::ROT_INVALID) {
135613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            orientation = 0;
135713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        }
135813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
135913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mSurfaceFlingerConsumer->setTransformHint(orientation);
136013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian}
136113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
136213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
136313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// debugging
136413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ----------------------------------------------------------------------------
136513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopianvoid Layer::dump(String8& result, Colorizer& colorizer) const
13671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
13681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const Layer::State& s(getDrawingState());
136913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.colorize(result, Colorizer::GREEN);
137174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
137213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "+ %s %p (%s)\n",
137313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            getTypeId(), this, getName().string());
13743e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
137513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
13762ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian    s.activeTransparentRegion.dump(result, "transparentRegion");
137713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    visibleRegion.dump(result, "visibleRegion");
1378ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
137913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Client> client(mClientRef.promote());
138013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
138174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(            "      "
138213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
138313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "isOpaque=%1d, invalidate=%1d, "
138413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
138513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            "      client=%p\n",
138613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
138713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.left, s.active.crop.top,
138813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.active.crop.right, s.active.crop.bottom,
13894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            isOpaque(s), contentDirty,
139013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.alpha, s.flags,
139113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[0][0], s.transform[0][1],
139213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            s.transform[1][0], s.transform[1][1],
139313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            client.get());
13941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1395a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
1396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
13971b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
13981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
13991b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
14001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
1401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
14021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
140374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
14041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
1405ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
14066905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
1407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
14086905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
14091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1410bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
141174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        mSurfaceFlingerConsumer->dump(result, "            ");
1412bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
1413d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
1414d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
1415d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::dumpFrameStats(String8& result) const {
1416d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.dumpStats(result);
141782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
141882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
1419d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::clearFrameStats() {
1420d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.clearStats();
142125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
142225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
14236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid Layer::logFrameStats() {
14246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mFrameTracker.logAndResetStats(mName);
14256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
14266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
1427d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavvoid Layer::getFrameStats(FrameStats* outStats) const {
1428d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mFrameTracker.getStats(outStats);
1429d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
1430d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
143113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian// ---------------------------------------------------------------------------
143213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
143313127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
143413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer)
143513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : mFlinger(flinger), mLayer(layer) {
1436b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
1437b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
143813127d8921356dff794250e04208c3ed60b3a3dfMathias AgopianLayer::LayerCleaner::~LayerCleaner() {
143913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    // destroy client resources
144013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    mFlinger->onLayerDestroyed(mLayer);
1441a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
1442a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
14443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
14473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
14483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
14513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
14523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
1453