Layer.cpp revision 882e3a39ed770b335a203e233b57127fde1c839e
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>
2290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <math.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/compiler.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <cutils/native_handle.h>
26a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <cutils/properties.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
359cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
390f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
401f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
43a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "SurfaceTextureLayer.h"
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
451b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
533ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianLayer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    :   LayerBaseClient(flinger, client),
55a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
56a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
57a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
58933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
59a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
6182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
625bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
631f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mGLExtensions(GLExtensions::getInstance()),
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mOpaqueLayer(true),
65b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
66933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mProtectedByApp(false)
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
68a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glGenTextures(1, &mTextureName);
70e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
71e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
73d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface* layer) {
74c39736088398a9b4367b30fc307ed7de96ac342eMathias Agopian    LayerBaseClient::onLayerDisplayed(hw, layer);
75ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (layer) {
76bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    }
78d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
80a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef()
8196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    LayerBaseClient::onFirstRef();
83ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian
84bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
85b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    sp<BufferQueue> bq = new SurfaceTextureLayer();
86bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
87a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian            GL_TEXTURE_EXTERNAL_OES, false, bq);
88b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
89bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
90bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
91bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setSynchronousMode(true);
92b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
937f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
947f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
95bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
967f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
97bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
98303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
996905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
1018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    updateTransformHint(hw);
102b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
10396f0819f81293076e652792794a961543e6750d7Mathias Agopian
104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer()
105b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
106921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
10796f0819f81293076e652792794a961543e6750d7Mathias Agopian}
10896f0819f81293076e652792794a961543e6750d7Mathias Agopian
109a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1103d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
11199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
113579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
114d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
115d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
116d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
117d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
118bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->abandon();
11948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
120cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
121a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) {
122a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    LayerBase::setName(name);
123bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setName(name);
124a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis}
125a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis
126a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface()
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
128882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden    /*
129882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * This class provides an implementation of BnSurface (the "native" or
130882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * "remote" side of the Binder IPC interface ISurface), and mixes in
131882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
132882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * this layer when the BSurface is destroyed.
133882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
134882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * The idea is to provide a handle to the Layer through ISurface that
135882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * is cleaned up automatically when the last reference to the ISurface
136882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * goes away.  (The references will be held on the "proxy" side, while
137882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * the Layer exists on the "native" side.)
138882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     *
139882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * The Layer has a reference to an instance of SurfaceFlinger's variant
140882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * of GLConsumer, which holds a reference to the BufferQueue.  The
141882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * getSurfaceTexture() call returns a Binder interface reference for
142882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     * the producer interface of the buffer queue associated with the Layer.
143882e3a39ed770b335a203e233b57127fde1c839eAndy McFadden     */
144a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class BSurface : public BnSurface, public LayerCleaner {
145a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
1462adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
1472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden            sp<IGraphicBufferProducer> res;
148a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<const Layer> that( mOwner.promote() );
149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != NULL) {
150bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden                res = that->mSurfaceFlingerConsumer->getBufferQueue();
151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return res;
153a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
154a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        BSurface(const sp<SurfaceFlinger>& flinger,
156a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const sp<Layer>& layer)
157a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) { }
158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
159a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> sur(new BSurface(mFlinger, this));
160a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    return sur;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const
164582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{
165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
166582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
167582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
168f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
171401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
174ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    if (err) {
175ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("unsupported pixelformat %d", format);
176ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        return err;
177ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    }
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
180a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
181ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
182ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
183ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
184ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
185ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
186ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
187ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
188ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
189cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
190eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
1913165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
1923165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
1933165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
194a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
195a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
196bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
197bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
198bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
199ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
203f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const {
204bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    // Start with the SurfaceFlingerConsumer's buffer crop...
205f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
206f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
207f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
208f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else  if (mActiveBuffer != NULL){
209f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
210f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
2114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
2124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        return crop;
213f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
214f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
215f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // ... then reduce that in the same proportions as the window crop reduces
216f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // the window size.
217f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    const State& s(drawingState());
21893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian    if (!s.active.crop.isEmpty()) {
219f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // Transform the window crop to match the buffer coordinate system,
220f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // which means using the inverse of the current transform set on the
221bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        // SurfaceFlingerConsumer.
222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        uint32_t invTransform = mCurrentTransform;
22393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winWidth = s.active.w;
22493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winHeight = s.active.h;
225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
22893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winWidth = s.active.h;
22993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winHeight = s.active.w;
230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
23193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        Rect winCrop = s.active.crop.transform(invTransform,
23293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                s.active.w, s.active.h);
233f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
234f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float xScale = float(crop.width()) / float(winWidth);
235f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float yScale = float(crop.height()) / float(winHeight);
23693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.left += int(ceilf(float(winCrop.left) * xScale));
23793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.top += int(ceilf(float(winCrop.top) * yScale));
23893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
23993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
240f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
241f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
244f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
2454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
2464297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
2474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
2494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    LayerBaseClient::setGeometry(hw, layer);
250a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
2513e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
2523e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
253a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
254a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
255a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
256a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
2573e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
258a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
259a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
260dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
261dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
262dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
263dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
26429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
26529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
26629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
26729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
26829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
26929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
27029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
27129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
27229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
2734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
27429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
27529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
27629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const uint32_t finalTransform = tr.getOrientation();
27729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
278a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
27929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    if (finalTransform & Transform::ROT_INVALID) {
2803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
281a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
2823e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setTransform(finalTransform);
283a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
2843e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setCrop(computeBufferCrop());
285a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
286a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2874297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
288d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
28971e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    LayerBaseClient::setPerFrameData(hw, layer);
2903e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
2913e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
29271e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    layer.setBuffer(mActiveBuffer);
293c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
294dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
2954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
296d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
297c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
298d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
299d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
300d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
301d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
302d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
303bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
304dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        if (fence.get()) {
305c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
306dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
307dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
308dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
309dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
310dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
311c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
312c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
313c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
3144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3161c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
3171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
318a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
329f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
330f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
3364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
340179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3411b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
342179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
345a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
34697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // Bind the current buffer to the GL texture, and wait for it to be
34797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden    // ready for us to draw into.
348bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
349bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (err != NO_ERROR) {
35097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
351dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
352dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
353dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
354dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
355dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
356dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
357dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
358cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
359eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
360cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
361cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
362cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
363bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
364bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
365cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
366cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
367c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
368c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        GLenum filter = GL_NEAREST;
369cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        if (useFiltering) {
370c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian            filter = GL_LINEAR;
3719575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        }
372c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
373c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
3749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
375cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        glLoadMatrixf(textureMatrix);
3769575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
377c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_2D);
3784c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet        glEnable(GL_TEXTURE_EXTERNAL_OES);
379a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
380c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
3819575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
3829575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glLoadIdentity();
3839575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
384c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
385c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glEnable(GL_TEXTURE_2D);
386a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
387a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
3881b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
389a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
390c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
391c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
394ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
395ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
396ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
397ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
398ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
399ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
400ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format)
402ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
403a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
405ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
406a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    PixelFormatInfo info;
407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
408a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // in case of error (unknown format), we assume no blending
409a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return (err || info.h_alpha <= info.l_alpha);
410ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
411ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
412ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
413a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
414a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
415a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
416a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
417db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
418a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
419db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
420a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
421a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
422a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
423a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
424a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
425a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
4267a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
4277a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
428a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
4297a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
4307a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4317a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
432b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4351c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4361c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4404824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
4414824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                             (temp.requested.h != front.requested.h);
442a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
443a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
444cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
4459d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
4466905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
448419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
4516905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
452419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.w, temp.active.h,
453419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.left,
454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.top,
455419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.right,
456419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.bottom,
457419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getWidth(),
458419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getHeight(),
459419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.requested.w, temp.requested.h,
460b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.left,
461b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.top,
462b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.right,
463b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.bottom,
464b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getWidth(),
465b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getHeight(),
466419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.w, front.active.h,
467419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.left,
468419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.top,
469419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.right,
470419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.bottom,
471419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getWidth(),
472419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getHeight(),
473419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.w, front.requested.h,
474b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.left,
475b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.top,
476b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.right,
477b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.bottom,
478b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.getWidth(),
479419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.crop.getHeight());
480a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
4812a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
4822a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
483bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->setDefaultBufferSize(
484b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.w, temp.requested.h);
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
486cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
4870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
4880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4890cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        const bool resizePending = (temp.requested.w != temp.active.w) ||
4900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian                                   (temp.requested.h != temp.active.h);
4910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
4930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // don't let LayerBase::doTransaction update the drawing state
4940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
4950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
4960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
4970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
4980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
4990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
5000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
5010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
5020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
5030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
5040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
5050cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
509a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const {
510933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
511a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
513a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const {
514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return !mCurrentCrop.isEmpty();
515a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
516a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5214d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
5224d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
5234d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
52499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
526d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
527d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
528bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
52982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
53082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
531bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
53282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (frameReadyFence != NULL) {
53382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
53482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
53582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
53682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
53782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
53882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
53982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
540d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
54182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
54246b6bce198c81ce9a4e0583e876d080ad48db003Jamie Gennis        // XXX: Temporarily don't use the present fence from HWC to work
54346b6bce198c81ce9a4e0583e876d080ad48db003Jamie Gennis        // around a driver bug.
54446b6bce198c81ce9a4e0583e876d080ad48db003Jamie Gennis        presentFence.clear();
54582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (presentFence != NULL) {
54682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
54782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
54882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
54982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
55082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
55182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
55282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
55382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
55482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
555d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
556d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
557d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
558d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
559da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
560da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
561da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
562da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5651c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5661c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
5674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
5683d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
56999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
57099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
57199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
57299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
57399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
57499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
5754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
57799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
57899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
579351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
580db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
581351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
582db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
5833d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        // signal another event if we have more frames pending
5843d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        if (android_atomic_dec(&mQueuedFrames) > 1) {
58599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mFlinger->signalLayerUpdate();
5863d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        }
5873d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis
588bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    const BufferQueue::BufferItem& item) {
6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
6202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
6232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
6242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
6282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
6292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
6352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
6362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
6396905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
6402c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
6412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
6426905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
6432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
6442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
6452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
6462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
6472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
6482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
6492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
6502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
6512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
6522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
6532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
6542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
6552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
6562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
6572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
6602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
6612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
6624824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
6632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
6642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
6672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
6682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
6692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
6722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
673bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) {
674a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
675a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
6764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
677a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
678d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
679351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
680bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
681e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
682e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
684e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
685da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6864824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
687702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
688e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
6892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
6902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
691ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
6922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
693702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
694bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
695bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
696bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
697702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
698702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
699702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
700702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
701702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
702702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
703702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
704ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
705702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
706702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
707702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
708e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
709e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
710702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
711702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
712ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
713702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
714702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
715702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
716702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
717702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
718702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
719702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
720702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
721702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
722702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
7254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const Layer::State& front(drawingState());
7264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        Region dirtyRegion(Rect(front.active.w, front.active.h));
7271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
7294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        outDirtyRegion = (front.transform.transform(dirtyRegion));
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
7314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7361b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7371b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
738a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
739a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
7401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7421b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7431b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
744a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
7451b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7461b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
748ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
7496905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
750a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
7516905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
7521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
754d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
755bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    if (mSurfaceFlingerConsumer != 0) {
756bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
757bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
758d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
759d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
76082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
76182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
76282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    LayerBaseClient::dumpStats(result, buffer, SIZE);
763b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    const nsecs_t period =
764b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
76582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.appendFormat("%lld\n", period);
76682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
76782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
76882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
76925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats()
77025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
77125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    LayerBaseClient::clearStats();
77282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
77325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
77425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
775a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
776b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
777a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // TODO: should we do something special if mSecure is set?
778a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mProtectedByApp) {
779a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        // need a hardware-protected path to external video sink
780a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
781b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
7823599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
783a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return usage;
784b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
785b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
7868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopianvoid Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
787a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    uint32_t orientation = 0;
788a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
7898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint is used to improve performance, but we can
7908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // only have a single transform hint, it cannot
7914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // apply to all displays.
7924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& planeTransform(hw->getTransform());
7934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        orientation = planeTransform.getOrientation();
794a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        if (orientation & Transform::ROT_INVALID) {
795a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            orientation = 0;
796a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        }
797a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    }
798bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden    mSurfaceFlingerConsumer->setTransformHint(orientation);
799a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
800a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
805