Layer.cpp revision 82dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6add
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) {
76ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    }
78d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
79d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
80a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef()
8196f0819f81293076e652792794a961543e6750d7Mathias Agopian{
82a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    LayerBaseClient::onFirstRef();
83ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian
84b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // Creates a custom BufferQueue for SurfaceTexture to use
85b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    sp<BufferQueue> bq = new SurfaceTextureLayer();
86b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture = new SurfaceTexture(mTextureName, true,
87a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian            GL_TEXTURE_EXTERNAL_OES, false, bq);
88b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
89b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
90a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkin    mSurfaceTexture->setFrameAvailableListener(this);
91a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setSynchronousMode(true);
92b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
937f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
947f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
9531a353da225af5329735451c761b430d82dfda1bJamie Gennis    mSurfaceTexture->setDefaultMaxBufferCount(2);
967f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
9731a353da225af5329735451c761b430d82dfda1bJamie Gennis    mSurfaceTexture->setDefaultMaxBufferCount(3);
98303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
996905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden
1006905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden    updateTransformHint();
101b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
10296f0819f81293076e652792794a961543e6750d7Mathias Agopian
103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer()
104b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
105921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
10696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
10796f0819f81293076e652792794a961543e6750d7Mathias Agopian
108a4a3149a36bc69a06e4824aeae909ab910661070Igor Murashkinvoid Layer::onFrameAvailable() {
1093d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
11099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
111579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
112579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
113d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
114d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
115d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
116d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
117dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis    mSurfaceTexture->abandon();
11848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
119cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
120a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) {
121a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    LayerBase::setName(name);
122a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    mSurfaceTexture->setName(name);
123a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis}
124a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis
125a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface()
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
127a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class BSurface : public BnSurface, public LayerCleaner {
128a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
129a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
130a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<ISurfaceTexture> res;
131a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<const Layer> that( mOwner.promote() );
132a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != NULL) {
133b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam                res = that->mSurfaceTexture->getBufferQueue();
134a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
135a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return res;
136a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
137a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
138a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        BSurface(const sp<SurfaceFlinger>& flinger,
139a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const sp<Layer>& layer)
140a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) { }
141a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
142a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> sur(new BSurface(mFlinger, this));
143a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    return sur;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const
147582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{
148b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return mSurfaceTexture->getBufferQueue()->asBinder();
149582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
150582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
151f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
154401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
157ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    if (err) {
158ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("unsupported pixelformat %d", format);
159ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        return err;
160ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    }
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
163a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
164ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
165ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
166ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
167ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
168ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
169ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
170ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
171ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
172cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
173eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
1743165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
1753165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
1763165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
177a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
178a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
179a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferSize(w, h);
180a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferFormat(format);
181b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
182ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
186f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const {
187f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // Start with the SurfaceTexture's buffer crop...
188f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
189f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
190f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
191f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else  if (mActiveBuffer != NULL){
192f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
193f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
1944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
1954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        return crop;
196f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
197f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
198f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // ... then reduce that in the same proportions as the window crop reduces
199f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // the window size.
200f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    const State& s(drawingState());
20193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian    if (!s.active.crop.isEmpty()) {
202f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // Transform the window crop to match the buffer coordinate system,
203f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // which means using the inverse of the current transform set on the
204f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // SurfaceTexture.
205f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        uint32_t invTransform = mCurrentTransform;
20693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winWidth = s.active.w;
20793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winHeight = s.active.h;
208f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
209f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
210f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
21193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winWidth = s.active.h;
21293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winHeight = s.active.w;
213f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
21493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        Rect winCrop = s.active.crop.transform(invTransform,
21593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                s.active.w, s.active.h);
216f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
217f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float xScale = float(crop.width()) / float(winWidth);
218f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float yScale = float(crop.height()) / float(winHeight);
21993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.left += int(ceilf(float(winCrop.left) * xScale));
22093ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.top += int(ceilf(float(winCrop.top) * yScale));
22193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
22293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
224f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
2284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
2294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
2304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
231a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
2324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    LayerBaseClient::setGeometry(hw, layer);
233a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
2343e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
2353e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
236a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
237a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
238a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
239a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
2403e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
241a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
242a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
243dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (isSecure() && !hw->isSecure()) {
244dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        layer.setSkip(true);
245dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    }
246dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
24729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
24829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
24929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
25029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
25129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
25229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
25329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
25429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
25529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
2564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
25729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
25829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
25929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const uint32_t finalTransform = tr.getOrientation();
26029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
261a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
26229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    if (finalTransform & Transform::ROT_INVALID) {
2633e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
264a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
2653e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setTransform(finalTransform);
266a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
2673e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setCrop(computeBufferCrop());
268a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
269a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
271d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
27271e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    LayerBaseClient::setPerFrameData(hw, layer);
2733e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
2743e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
27571e83e1202dc87afde9c0c31f31c129f3f99263fMathias Agopian    layer.setBuffer(mActiveBuffer);
276c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
277dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
2784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
279d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
280c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
281d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
282d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
283d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
284d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
285d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
286dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        sp<Fence> fence = mSurfaceTexture->getCurrentFence();
287dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        if (fence.get()) {
288c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
289dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
290dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
291dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
292dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
293dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
294c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
295c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
296c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
2974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2991c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
3001c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
301a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
303179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
304179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
305179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
306179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
307179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
308179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
309179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
310179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
311179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
312f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
313f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
314179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
315179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
316179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
318179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
3194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3241b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
328a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
32961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis    status_t err = mSurfaceTexture->doGLFenceWait();
33061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis    if (err != OK) {
33161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis        ALOGE("onDraw: failed waiting for fence: %d", err);
332dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
333dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
334dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
335dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
336dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
337dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
338dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    if (!blackOutLayer) {
339cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
340eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
341cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
342cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
343cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
344cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->setFilteringEnabled(useFiltering);
345cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->getTransformMatrix(textureMatrix);
346cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
347cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
348c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
349c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        GLenum filter = GL_NEAREST;
350cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        if (useFiltering) {
351c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian            filter = GL_LINEAR;
3529575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        }
353c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
354c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
3559575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
356cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        glLoadMatrixf(textureMatrix);
3579575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
358c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_2D);
3594c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet        glEnable(GL_TEXTURE_EXTERNAL_OES);
360a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
361c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
3629575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
3639575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glLoadIdentity();
3649575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
365c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
366c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glEnable(GL_TEXTURE_2D);
367a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
368a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
3691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
370a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
371c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
372c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
375ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
376ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
377ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
378ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
379ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
380ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
381ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
382a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format)
383ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
384a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
385a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
386ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
387a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    PixelFormatInfo info;
388a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
389a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // in case of error (unknown format), we assume no blending
390a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return (err || info.h_alpha <= info.l_alpha);
391ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
392ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
393ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
394a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
395a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
397a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
398db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
399a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
400db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
401a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
402a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
403a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
405a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
406a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
4077a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
4087a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
409a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
4107a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
4117a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4127a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
413b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4161c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4214824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
4224824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                             (temp.requested.h != front.requested.h);
423a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
424a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
425cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
4269d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
4276905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
428419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
429419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
430419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
431419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
4326905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
433419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.w, temp.active.h,
434419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.left,
435419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.top,
436419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.right,
437419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.bottom,
438419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getWidth(),
439419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getHeight(),
440419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.requested.w, temp.requested.h,
441b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.left,
442b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.top,
443b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.right,
444b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.bottom,
445b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getWidth(),
446b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getHeight(),
447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.w, front.active.h,
448419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.left,
449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.top,
450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.right,
451419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.bottom,
452419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getWidth(),
453419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getHeight(),
454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.w, front.requested.h,
455b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.left,
456b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.top,
457b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.right,
458b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.bottom,
459b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.getWidth(),
460419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.crop.getHeight());
461a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
4622a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
4632a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
464b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian        mSurfaceTexture->setDefaultBufferSize(
465b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.w, temp.requested.h);
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
467cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
4680cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
4690cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4700cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        const bool resizePending = (temp.requested.w != temp.active.w) ||
4710cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian                                   (temp.requested.h != temp.active.h);
4720cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4730cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
4740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // don't let LayerBase::doTransaction update the drawing state
4750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
4760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
4770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
4780cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
4790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
4800cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
4810cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
4820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
4840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
4850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
4860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
490a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const {
491933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
492a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
493a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
494a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const {
495a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return !mCurrentCrop.isEmpty();
496a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
497a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5024d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
5034d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
5044d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
50599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
50699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
507d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
508d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
50982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        nsecs_t desiredPresentTime = mSurfaceTexture->getTimestamp();
51082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.setDesiredPresentTime(desiredPresentTime);
51182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
51282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> frameReadyFence = mSurfaceTexture->getCurrentFence();
51382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (frameReadyFence != NULL) {
51482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyFence(frameReadyFence);
51582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
51682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // There was no fence for this frame, so assume that it was ready
51782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // to be presented at the desired present time.
51882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setFrameReadyTime(desiredPresentTime);
51982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
52082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
521d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
52282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
52382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (presentFence != NULL) {
52482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentFence(presentFence);
52582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        } else {
52682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // The HWC doesn't support present fences, so use the refresh
52782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            // timestamp instead.
52882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
52982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            mFrameTracker.setActualPresentTime(presentTime);
53082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
53182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
53282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        mFrameTracker.advanceFrame();
533d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
534d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
535d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
536d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
537da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianbool Layer::isVisible() const {
538da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
539da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
540da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5431c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
5454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
5463d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
54899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
54999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
55099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
55199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
55299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
5534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
5544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
55599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
55699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
557351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
558db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
559351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
560db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
5613d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        // signal another event if we have more frames pending
5623d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        if (android_atomic_dec(&mQueuedFrames) > 1) {
56399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mFlinger->signalLayerUpdate();
5643d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        }
5653d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis
5662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        struct Reject : public SurfaceTexture::BufferRejecter {
5672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
5682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
5692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
5702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
5712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
5722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
5732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
5742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
5752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
5772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    const BufferQueue::BufferItem& item) {
5782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
5792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
5802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
5812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
6176905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
6206905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
6232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
6242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
6282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
6292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
6352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
6392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
6404824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
6412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
6422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
6452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
6462c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
6472c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6482c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6492c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
6502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6513941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis        if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) {
652a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
653a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
655a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
656d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
657351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
658351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
659e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
660e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
662e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
663da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6644824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
665702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
666e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
6672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
6682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
669ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
6702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
671702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
672702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        Rect crop(mSurfaceTexture->getCurrentCrop());
6732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
6742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
675702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
676702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
677702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
678702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
679702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
680702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
681702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
682ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden            recomputeVisibleRegions = true;
683702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
684702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
685702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
686e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
687e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
688702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
689702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
690ab10c5804c250e7f392c8262f687766edec2e9f4Andy McFadden                recomputeVisibleRegions = true;
691702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
692702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
693702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
694702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
695702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
696702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
697702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
698702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
699702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
700702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const Layer::State& front(drawingState());
7044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        Region dirtyRegion(Rect(front.active.w, front.active.h));
7051c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        outDirtyRegion = (front.transform.transform(dirtyRegion));
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
7094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7151b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
716a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
717a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
7181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7201b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7211b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
722a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
7231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
726ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
7276905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            " queued-frames=%d, mRefreshPending=%d\n",
728a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
7296905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden            mQueuedFrames, mRefreshPending);
7301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
732d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
733a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mSurfaceTexture != 0) {
734a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
735bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
736d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
737d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
73882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
73982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
74082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    LayerBaseClient::dumpStats(result, buffer, SIZE);
741b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    const nsecs_t period =
742b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
74382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.appendFormat("%lld\n", period);
74482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.dump(result);
74582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
74682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
74725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats()
74825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
74925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    LayerBaseClient::clearStats();
75082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    mFrameTracker.clear();
75125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
75225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
753a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
754b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
755a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // TODO: should we do something special if mSecure is set?
756a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mProtectedByApp) {
757a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        // need a hardware-protected path to external video sink
758a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
759b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
7603599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
761a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return usage;
762b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
763b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
7646905205c8d130b6ea3a813c1b9283492ed183367Andy McFaddenvoid Layer::updateTransformHint() const {
765a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    uint32_t orientation = 0;
766a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
7674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // The transform hint is used to improve performance on the main
7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // display -- we can only have a single transform hint, it cannot
7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // apply to all displays.
7704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // This is why we use the default display here. This is not an
7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // oversight.
7724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
7734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& planeTransform(hw->getTransform());
7744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        orientation = planeTransform.getOrientation();
775a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        if (orientation & Transform::ROT_INVALID) {
776a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            orientation = 0;
777a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        }
778a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    }
7796905205c8d130b6ea3a813c1b9283492ed183367Andy McFadden    mSurfaceTexture->setTransformHint(orientation);
780a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
781a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
786