Layer.cpp revision 31a353da225af5329735451c761b430d82dfda1b
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),
6282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyOffset(0),
635bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
641f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mGLExtensions(GLExtensions::getInstance()),
65a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mOpaqueLayer(true),
66b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
67933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mProtectedByApp(false)
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
69a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glGenTextures(1, &mTextureName);
71e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
72e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
74d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface* 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
84a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
85a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
86a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    private:
87a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<Layer> mLayer;
88a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual void onFrameAvailable() {
89a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<Layer> that(mLayer.promote());
90a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != 0) {
91a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                that->onFrameQueued();
92a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
93a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
94a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
95b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
96b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // Creates a custom BufferQueue for SurfaceTexture to use
97b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    sp<BufferQueue> bq = new SurfaceTextureLayer();
98b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture = new SurfaceTexture(mTextureName, true,
99a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian            GL_TEXTURE_EXTERNAL_OES, false, bq);
100b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
101b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
102a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setSynchronousMode(true);
104b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1057f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1067f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
10731a353da225af5329735451c761b430d82dfda1bJamie Gennis    mSurfaceTexture->setDefaultMaxBufferCount(2);
1087f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
10931a353da225af5329735451c761b430d82dfda1bJamie Gennis    mSurfaceTexture->setDefaultMaxBufferCount(3);
110303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
111b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
11296f0819f81293076e652792794a961543e6750d7Mathias Agopian
113a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer()
114b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
115921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mFlinger->deleteTextureAsync(mTextureName);
11696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
11796f0819f81293076e652792794a961543e6750d7Mathias Agopian
118a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFrameQueued() {
1193d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
121579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
122579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
123d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
124d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
125d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
126d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
127dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis    mSurfaceTexture->abandon();
12848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
129cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
130a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) {
131a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    LayerBase::setName(name);
132a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    mSurfaceTexture->setName(name);
133a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis}
134a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis
135a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface()
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class BSurface : public BnSurface, public LayerCleaner {
138a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
139a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
140a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<ISurfaceTexture> res;
141a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<const Layer> that( mOwner.promote() );
142a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != NULL) {
143b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam                res = that->mSurfaceTexture->getBufferQueue();
144a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
145a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return res;
146a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
147a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
148a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        BSurface(const sp<SurfaceFlinger>& flinger,
149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const sp<Layer>& layer)
150a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) { }
151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> sur(new BSurface(mFlinger, this));
153a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    return sur;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const
157582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{
158b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return mSurfaceTexture->getBufferQueue()->asBinder();
159582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
160582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
161f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
167ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    if (err) {
168ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("unsupported pixelformat %d", format);
169ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        return err;
170ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    }
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
172ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
173a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
174ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
175ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
176ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
177ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
178ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
179ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
180ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
181ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
182cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
183eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
1843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
1853165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
1863165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
187a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
188a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
189a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferSize(w, h);
190a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferFormat(format);
191b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
192ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
196f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const {
197f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // Start with the SurfaceTexture's buffer crop...
198f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
199f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
200f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
201f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else  if (mActiveBuffer != NULL){
202f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
203f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
2044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        crop.makeInvalid();
2054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        return crop;
206f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
207f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
208f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // ... then reduce that in the same proportions as the window crop reduces
209f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // the window size.
210f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    const State& s(drawingState());
21193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian    if (!s.active.crop.isEmpty()) {
212f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // Transform the window crop to match the buffer coordinate system,
213f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // which means using the inverse of the current transform set on the
214f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // SurfaceTexture.
215f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        uint32_t invTransform = mCurrentTransform;
21693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winWidth = s.active.w;
21793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winHeight = s.active.h;
218f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
219f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
220f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
22193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winWidth = s.active.h;
22293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winHeight = s.active.w;
223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
22493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        Rect winCrop = s.active.crop.transform(invTransform,
22593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                s.active.w, s.active.h);
226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float xScale = float(crop.width()) / float(winWidth);
228f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float yScale = float(crop.height()) / float(winHeight);
22993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.left += int(ceilf(float(winCrop.left) * xScale));
23093ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.top += int(ceilf(float(winCrop.top) * yScale));
23193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
23293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
233f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
234f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
235f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
236f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
237f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
2384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid Layer::setGeometry(
2394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const sp<const DisplayDevice>& hw,
2404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        HWComposer::HWCLayerInterface& layer)
241a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
2424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    LayerBaseClient::setGeometry(hw, layer);
243a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
2443e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
2453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
246a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
247a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
248a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
249a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
2503e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
251a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
252a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
25329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
25429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
25529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
25629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
25729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
25829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
25929a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
26029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
26129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
2624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
26329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
26429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
26529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const uint32_t finalTransform = tr.getOrientation();
26629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
267a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
26829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    if (finalTransform & Transform::ROT_INVALID) {
2693e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
270a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
2713e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setTransform(finalTransform);
272a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
2733e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setCrop(computeBufferCrop());
274a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
275a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
277d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
278c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian    const sp<GraphicBuffer>& buffer(mActiveBuffer);
2793e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
2803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
2813e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setBuffer(buffer);
282c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall}
283dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
2844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
285d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        HWComposer::HWCLayerInterface& layer) {
286c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    int fenceFd = -1;
287d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
288d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // TODO: there is a possible optimization here: we only need to set the
289d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    // acquire fence the first time a new buffer is acquired on EACH display.
290d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
291d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (layer.getCompositionType() == HWC_OVERLAY) {
292dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        sp<Fence> fence = mSurfaceTexture->getCurrentFence();
293dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        if (fence.get()) {
294c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            fenceFd = fence->dup();
295dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
296dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
297dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
298dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
299dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
300c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    layer.setAcquireFenceFd(fenceFd);
301c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
302c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
3034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3051c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
3061c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
307a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
309179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
310179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
311179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
312179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
313179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
314179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
315179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
316179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
317179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
318f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
319f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
320179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
321179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
3254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3301b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
334a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
335dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    // TODO: replace this with a server-side wait
336dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    sp<Fence> fence = mSurfaceTexture->getCurrentFence();
337dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    if (fence.get()) {
338dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        status_t err = fence->wait(Fence::TIMEOUT_NEVER);
339dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        ALOGW_IF(err != OK, "Layer::onDraw: failed waiting for fence: %d", err);
340dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
341dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
342dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
343dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
3449575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    if (!isProtected()) {
345cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
346cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
347cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
348cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
349cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
350cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->setFilteringEnabled(useFiltering);
351cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->getTransformMatrix(textureMatrix);
352cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
353cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
354c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
355c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        GLenum filter = GL_NEAREST;
356cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        if (useFiltering) {
357c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian            filter = GL_LINEAR;
3589575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        }
359c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
360c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
3619575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
362cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        glLoadMatrixf(textureMatrix);
3639575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
364c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_2D);
3654c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet        glEnable(GL_TEXTURE_EXTERNAL_OES);
366a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
367c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
3689575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
3699575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glLoadIdentity();
3709575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
371c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
372c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glEnable(GL_TEXTURE_2D);
373a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
374a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
3751b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
376a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
377c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
378c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
381ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
382ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
383ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
384ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
385ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
386ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
387ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
388a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format)
389ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
390a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
391a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
392ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
393a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    PixelFormatInfo info;
394a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
395a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // in case of error (unknown format), we assume no blending
396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return (err || info.h_alpha <= info.l_alpha);
397ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
398ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
399ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
400a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
401a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
402a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
403a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
404db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
405a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
406db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
408a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
409a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
410a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
411a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
412a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
4137a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
4147a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
415a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
4167a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
4177a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4187a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
419b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4231c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4274824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
4284824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                             (temp.requested.h != front.requested.h);
429a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
430a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
431cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
4329d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
433419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
434419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
435419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
436419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
437419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
438419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                this, mCurrentScalingMode,
439419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.w, temp.active.h,
440419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.left,
441419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.top,
442419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.right,
443419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.bottom,
444419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getWidth(),
445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getHeight(),
446419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.requested.w, temp.requested.h,
447b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.left,
448b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.top,
449b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.right,
450b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.bottom,
451b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getWidth(),
452b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getHeight(),
453419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.w, front.active.h,
454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.left,
455419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.top,
456419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.right,
457419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.bottom,
458419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getWidth(),
459419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getHeight(),
460419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.w, front.requested.h,
461b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.left,
462b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.top,
463b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.right,
464b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.bottom,
465b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.getWidth(),
466419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.crop.getHeight());
467a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
4682a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
4692a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
470b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian        mSurfaceTexture->setDefaultBufferSize(
471b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.w, temp.requested.h);
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
473cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
4740cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
4750cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4760cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        const bool resizePending = (temp.requested.w != temp.active.w) ||
4770cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian                                   (temp.requested.h != temp.active.h);
4780cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4790cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
4800cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // don't let LayerBase::doTransaction update the drawing state
4810cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
4820cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
4830cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
4840cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
4850cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
4860cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
4870cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
4880cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4890cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
4900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
4910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
4920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
496a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const {
497933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
498a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
499a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
500a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const {
501a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return !mCurrentCrop.isEmpty();
502a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
503a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5084d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
5094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
5104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
51199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
51299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
513d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid Layer::onPostComposition() {
514d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    if (mFrameLatencyNeeded) {
515d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const HWComposer& hwc = mFlinger->getHwComposer();
516d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        const size_t offset = mFrameLatencyOffset;
517d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp();
518d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameStats[offset].set = systemTime();
519d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameStats[offset].vsync = hwc.getRefreshTimestamp();
520d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
521d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        mFrameLatencyNeeded = false;
522d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
523d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
524d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
5254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion Layer::latchBuffer(bool& recomputeVisibleRegions)
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5281c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
5294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region outDirtyRegion;
5303d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
5374d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
5384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
541351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
542db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
543351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
544db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
5453d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        // signal another event if we have more frames pending
5463d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        if (android_atomic_dec(&mQueuedFrames) > 1) {
54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mFlinger->signalLayerUpdate();
5483d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        }
5493d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis
5502c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        struct Reject : public SurfaceTexture::BufferRejecter {
5512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
5522c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
5532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
5542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
5552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
5562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
5572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
5582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
5592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
5612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    const BufferQueue::BufferItem& item) {
5622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
5632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
5642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
5652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
5672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
5682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
5702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
5712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
5722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
5732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
5742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
5772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
5782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
5802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
5812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
5822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
6172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
6232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
6244824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
6292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // XXX: not sure if setTransformHint belongs here
6364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // it should only be needed when the main screen orientation changes
6374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mSurfaceTexture->setTransformHint(getTransformHint());
6384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
6424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
643a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
644d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
645351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
646351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
647e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (mActiveBuffer == NULL) {
648e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            // this can only happen if the very first buffer was rejected.
6494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            return outDirtyRegion;
650e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
651da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6524824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
653702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
654e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
6552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
6562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
6572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             mFlinger->invalidateHwcGeometry();
6582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
659702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
660702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        Rect crop(mSurfaceTexture->getCurrentCrop());
6612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
6622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
663702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
664702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
665702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
666702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
667702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
668702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
669702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
670702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mFlinger->invalidateHwcGeometry();
671702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
672702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
673702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
674e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
675e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
676702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
677702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
678702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                mFlinger->invalidateHwcGeometry();
679702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
680702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
681702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
682702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
683702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
684702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
685702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
686702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
687702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
688702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // FIXME: postedRegion should be dirty & bounds
6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const Layer::State& front(drawingState());
6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        Region dirtyRegion(Rect(front.active.w, front.active.h));
6931c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // transform the dirty region to window-manager space
6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        outDirtyRegion = (front.transform.transform(dirtyRegion));
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return outDirtyRegion;
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7011b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7031b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
704a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
705a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
7061b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7071b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7091b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
710a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
7111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
714ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
71599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
716a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            getTransformHint(), mQueuedFrames, mRefreshPending);
7181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7191b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
720d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
721a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mSurfaceTexture != 0) {
722a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
723bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
724d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
725d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
72682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
72782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
72882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    LayerBaseClient::dumpStats(result, buffer, SIZE);
72982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t o = mFrameLatencyOffset;
730888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    const nsecs_t period = mFlinger->getHwComposer().getRefreshPeriod();
73182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.appendFormat("%lld\n", period);
73282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<128 ; i++) {
73382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const size_t index = (o+i) % 128;
73482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_app   = mFrameStats[index].timestamp;
73582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_set   = mFrameStats[index].set;
73682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_vsync = mFrameStats[index].vsync;
73782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        result.appendFormat("%lld\t%lld\t%lld\n",
73882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_app,
73982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_vsync,
74082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_set);
74182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
74282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append("\n");
74382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
74482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
74525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats()
74625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
74725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    LayerBaseClient::clearStats();
74825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    memset(mFrameStats, 0, sizeof(mFrameStats));
74925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
75025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
751a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
752b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
753a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // TODO: should we do something special if mSecure is set?
754a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mProtectedByApp) {
755a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        // need a hardware-protected path to external video sink
756a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
757b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
7583599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
759a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return usage;
760b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
761b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
762a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianuint32_t Layer::getTransformHint() const {
763a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    uint32_t orientation = 0;
764a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
7654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // The transform hint is used to improve performance on the main
7664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // display -- we can only have a single transform hint, it cannot
7674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // apply to all displays.
7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // This is why we use the default display here. This is not an
7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // oversight.
7704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
7714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& planeTransform(hw->getTransform());
7724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        orientation = planeTransform.getOrientation();
773a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        if (orientation & Transform::ROT_INVALID) {
774a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            orientation = 0;
775a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        }
776a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    }
777a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    return orientation;
778a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
779a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
784