Layer.cpp revision dc5b485f74edf2d2f31c62054eb6c180421a3ade
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"
391b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.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
5396f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger,
5496f0819f81293076e652792794a961543e6750d7Mathias Agopian        DisplayID display, const sp<Client>& client)
5596f0819f81293076e652792794a961543e6750d7Mathias Agopian    :   LayerBaseClient(flinger, display, client),
56a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mTextureName(-1U),
57a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mQueuedFrames(0),
58a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentTransform(0),
59933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
60a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mCurrentOpacity(true),
614d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending(false),
6282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyNeeded(false),
63dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        mNeedHwcFence(false),
6482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameLatencyOffset(0),
655bf3abefb2745bf0c45b0814cfd44b4682060a6cMathias Agopian        mFormat(PIXEL_FORMAT_NONE),
661f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mGLExtensions(GLExtensions::getInstance()),
67a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mOpaqueLayer(true),
68b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
69933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mProtectedByApp(false)
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
72a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glGenTextures(1, &mTextureName);
73e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
74e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
75ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallvoid Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) {
76ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (layer) {
77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
78ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    }
79ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall
80e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (mFrameLatencyNeeded) {
811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        // we need a DisplayHardware for debugging only right now
821b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        // XXX: should this be called per DisplayHardware?
831b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
8482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
8582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameStats[mFrameLatencyOffset].set = systemTime();
8682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
87e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
88e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        mFrameLatencyNeeded = false;
89e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
90d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
91d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
92a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef()
9396f0819f81293076e652792794a961543e6750d7Mathias Agopian{
94a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    LayerBaseClient::onFirstRef();
95ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian
96a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
97a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
98a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    private:
99a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<Layer> mLayer;
100a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual void onFrameAvailable() {
101a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<Layer> that(mLayer.promote());
102a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != 0) {
103a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                that->onFrameQueued();
104a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
105a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
106a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
107b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
108b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // Creates a custom BufferQueue for SurfaceTexture to use
109b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    sp<BufferQueue> bq = new SurfaceTextureLayer();
110b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture = new SurfaceTexture(mTextureName, true,
111a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian            GL_TEXTURE_EXTERNAL_OES, false, bq);
112b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
113b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
114a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
115a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setSynchronousMode(true);
116b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1177f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1187f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
119a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setBufferCountServer(2);
1207f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
1217f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian    mSurfaceTexture->setBufferCountServer(3);
122303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
12496f0819f81293076e652792794a961543e6750d7Mathias Agopian
125a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer()
126b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
127118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mFlinger->postMessageAsync(
128118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
12996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
13096f0819f81293076e652792794a961543e6750d7Mathias Agopian
131a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFrameQueued() {
1323d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
13399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
134579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
135579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
136d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
137d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
138d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
139d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
140dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis    mSurfaceTexture->abandon();
14148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
142cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
143a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) {
144a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    LayerBase::setName(name);
145a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    mSurfaceTexture->setName(name);
146a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis}
147a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis
1481b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid Layer::validateVisibility(const Transform& globalTransform, const DisplayHardware& hw) {
1491b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    LayerBase::validateVisibility(globalTransform, hw);
150b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
151b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // This optimization allows the SurfaceTexture to bake in
152b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // the rotation so hardware overlays can be used
153b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setTransformHint(getTransformHint());
154b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam}
155b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
156a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface()
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class BSurface : public BnSurface, public LayerCleaner {
159a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
160a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
161a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<ISurfaceTexture> res;
162a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<const Layer> that( mOwner.promote() );
163a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != NULL) {
164b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam                res = that->mSurfaceTexture->getBufferQueue();
165a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
166a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return res;
167a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
168a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
169a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        BSurface(const sp<SurfaceFlinger>& flinger,
170a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const sp<Layer>& layer)
171a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) { }
172a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
173a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> sur(new BSurface(mFlinger, this));
174a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    return sur;
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
177582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const
178582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{
179b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return mSurfaceTexture->getBufferQueue()->asBinder();
180582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
181582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
182f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
185401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
188ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    if (err) {
189ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("unsupported pixelformat %d", format);
190ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        return err;
191ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    }
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
193401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
1941b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    // XXX: we shouldn't rely on the DisplayHardware to do this
1951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
196ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
197ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
198ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
199ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
200ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
201ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
202ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
203ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
204ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
205ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
206cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
207eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
2083330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
20916f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
210a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
211a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
212a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
213a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferSize(w, h);
214a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferFormat(format);
215b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
216ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const {
221f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // Start with the SurfaceTexture's buffer crop...
222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
224f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else  if (mActiveBuffer != NULL){
226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
228f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mTransformedBounds.width(), mTransformedBounds.height());
229f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
231f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // ... then reduce that in the same proportions as the window crop reduces
232f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // the window size.
233f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    const State& s(drawingState());
23493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian    if (!s.active.crop.isEmpty()) {
235f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // Transform the window crop to match the buffer coordinate system,
236f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // which means using the inverse of the current transform set on the
237f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // SurfaceTexture.
238f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        uint32_t invTransform = mCurrentTransform;
23993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winWidth = s.active.w;
24093ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winHeight = s.active.h;
241f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
24493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winWidth = s.active.h;
24593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winHeight = s.active.w;
246f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
24793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        Rect winCrop = s.active.crop.transform(invTransform,
24893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                s.active.w, s.active.h);
249f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
250f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float xScale = float(crop.width()) / float(winWidth);
251f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float yScale = float(crop.height()) / float(winHeight);
25293ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.left += int(ceilf(float(winCrop.left) * xScale));
25393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.top += int(ceilf(float(winCrop.top) * yScale));
25493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
25593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
256f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
257f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
258f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
259f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
260f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
2613e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopianvoid Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
262a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
2633e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    LayerBaseClient::setGeometry(layer);
264a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
2653e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // enable this layer
2663e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setSkip(false);
267a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
268a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can't do alpha-fade with the hwc HAL
269a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    const State& s(drawingState());
270a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (s.alpha < 0xFF) {
2713e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
272a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
273a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
27429a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    /*
27529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * Transformations are applied in this order:
27629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 1) buffer orientation/flip/mirror
27729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 2) state transformation (window manager)
27829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * 3) layer orientation (screen orientation)
279d992db3827016388e8069f5793b031153d423501Mathias Agopian     * mTransform is already the composition of (2) and (3)
28029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     * (NOTE: the matrices are multiplied in reverse order)
28129a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian     */
28229a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
28329a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const Transform bufferOrientation(mCurrentTransform);
284d992db3827016388e8069f5793b031153d423501Mathias Agopian    const Transform tr(mTransform * bufferOrientation);
28529a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
28629a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    // this gives us only the "orientation" component of the transform
28729a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    const uint32_t finalTransform = tr.getOrientation();
28829a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian
289a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // we can only handle simple transformation
29029a367bb7c14c916e991a6a0028727bd06c1e16eMathias Agopian    if (finalTransform & Transform::ROT_INVALID) {
2913e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setSkip(true);
292a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
2933e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer.setTransform(finalTransform);
294a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
2953e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setCrop(computeBufferCrop());
296a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
297a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2983e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopianvoid Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
299c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian    const sp<GraphicBuffer>& buffer(mActiveBuffer);
3003e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // NOTE: buffer can be NULL if the client never drew into this
3013e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    // layer yet, or if we ran out of memory
3023e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    layer.setBuffer(buffer);
303dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
304dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    if (mNeedHwcFence) {
305dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        sp<Fence> fence = mSurfaceTexture->getCurrentFence();
306dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        if (fence.get()) {
307dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            int fenceFd = fence->dup();
308dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            if (fenceFd == -1) {
309dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
310dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            }
311dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall            layer.setAcquireFenceFd(fenceFd);
312dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        }
313dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        mNeedHwcFence = false;
314dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    } else {
315dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        layer.setAcquireFenceFd(-1);
316dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
317c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
318c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
3191b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid Layer::onDraw(const DisplayHardware& hw, const Region& clip) const
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3211c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
3221c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
323a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
331179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
332179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
334f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
335f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
340179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
341179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
342179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
343179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
344179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
345179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
347179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
350a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
351dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    // TODO: replace this with a server-side wait
352dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    sp<Fence> fence = mSurfaceTexture->getCurrentFence();
353dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    if (fence.get()) {
354dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        status_t err = fence->wait(Fence::TIMEOUT_NEVER);
355dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        ALOGW_IF(err != OK, "Layer::onDraw: failed waiting for fence: %d", err);
356dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // Go ahead and draw the buffer anyway; no matter what we do the screen
357dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        // is probably going to have something visibly wrong.
358dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall    }
359dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall
3609575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    if (!isProtected()) {
361cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
362cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
363cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
364cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
365cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
366cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->setFilteringEnabled(useFiltering);
367cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->getTransformMatrix(textureMatrix);
368cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
369cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
370c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
371c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        GLenum filter = GL_NEAREST;
372cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        if (useFiltering) {
373c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian            filter = GL_LINEAR;
3749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        }
375c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
376c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
3779575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
378cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        glLoadMatrixf(textureMatrix);
3799575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
380c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_2D);
3814c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet        glEnable(GL_TEXTURE_EXTERNAL_OES);
382a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
383c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
3849575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
3859575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glLoadIdentity();
3869575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
387c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
388c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glEnable(GL_TEXTURE_2D);
389a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
390a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
3911b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    drawWithOpenGL(hw, clip);
392a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
393c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
394c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
397ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
398ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
399ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
400ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
401ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
402ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
403ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format)
405ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
406a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
408ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
409a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    PixelFormatInfo info;
410a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
411a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // in case of error (unknown format), we assume no blending
412a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return (err || info.h_alpha <= info.l_alpha);
413ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
414ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
415ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
416a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
417a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
418a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
419a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
420db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
421a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
422db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
423a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
424a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
425a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
426a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
427a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
428a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
4297a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
4307a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
431a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
4327a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
4337a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4347a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
435b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4381c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4391c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4434824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
4444824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                             (temp.requested.h != front.requested.h);
445a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
446a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
447cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
4489d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
451419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
452419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
453419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
454419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                this, mCurrentScalingMode,
455419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.w, temp.active.h,
456419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.left,
457419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.top,
458419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.right,
459419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.bottom,
460419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getWidth(),
461419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getHeight(),
462419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.requested.w, temp.requested.h,
463b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.left,
464b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.top,
465b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.right,
466b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.bottom,
467b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getWidth(),
468b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getHeight(),
469419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.w, front.active.h,
470419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.left,
471419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.top,
472419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.right,
473419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.bottom,
474419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getWidth(),
475419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getHeight(),
476419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.w, front.requested.h,
477b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.left,
478b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.top,
479b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.right,
480b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.bottom,
481b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.getWidth(),
482419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.crop.getHeight());
483a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
4842a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
4852a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
486b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian        mSurfaceTexture->setDefaultBufferSize(
487b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.w, temp.requested.h);
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
489cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
4900cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    if (!isFixedSize()) {
4910cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4920cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        const bool resizePending = (temp.requested.w != temp.active.w) ||
4930cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian                                   (temp.requested.h != temp.active.h);
4940cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
4950cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        if (resizePending) {
4960cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // don't let LayerBase::doTransaction update the drawing state
4970cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // if we have a pending resize, unless we are in fixed-size mode.
4980cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // the drawing state will be updated only once we receive a buffer
4990cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // with the correct size.
5000cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            //
5010cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // in particular, we want to make sure the clip (which is part
5020cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // of the geometry state) is latched together with the size but is
5030cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            // latched immediately when no resizing is involved.
5040cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
5050cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian            flags |= eDontUpdateGeometryState;
5060cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian        }
5070cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian    }
5080cd545f14261d829513e0d6e8fa5e4e4f3372b3dMathias Agopian
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const {
513933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
514a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
516a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const {
517a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return !mCurrentCrop.isEmpty();
518a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
519a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5244d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
5254d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
5264d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5311c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
5333d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
5404d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
5414d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            mPostedDirtyRegion.clear();
54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            return;
54399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
545351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
546db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
547351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
548db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
5493d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        // signal another event if we have more frames pending
5503d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        if (android_atomic_dec(&mQueuedFrames) > 1) {
55199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mFlinger->signalLayerUpdate();
5523d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        }
5533d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis
5542c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        struct Reject : public SurfaceTexture::BufferRejecter {
5552c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& front;
5562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Layer::State& current;
5572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            bool& recomputeVisibleRegions;
5582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            Reject(Layer::State& front, Layer::State& current,
5592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    bool& recomputeVisibleRegions)
5602c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                : front(front), current(current),
5612c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                  recomputeVisibleRegions(recomputeVisibleRegions) {
5622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
5632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5642c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            virtual bool reject(const sp<GraphicBuffer>& buf,
5652c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    const BufferQueue::BufferItem& item) {
5662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (buf == NULL) {
5672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    return false;
5682c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
5692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5702c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufWidth  = buf->getWidth();
5712c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                uint32_t bufHeight = buf->getHeight();
5722c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5732c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // check that we received a buffer of the right size
5742c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                // (Take the buffer's orientation into account)
5752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (item.mTransform & Transform::ROT_90) {
5762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    swap(bufWidth, bufHeight);
5772c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
5782c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5792c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5802c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
5812c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (front.active != front.requested) {
5822c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (isFixedSize ||
5842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            (bufWidth == front.requested.w &&
5852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                             bufHeight == front.requested.h))
5862c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    {
5872c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // Here we pretend the transaction happened by updating the
5882c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // current and drawing states. Drawing state is only accessed
5892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // in this thread, no need to have it locked
5902c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active = front.requested;
5912c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
5922c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // We also need to update the current state so that
5932c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // we don't end-up overwriting the drawing state with
5942c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // this stale current state during the next transaction
5952c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        //
5962c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // NOTE: We don't need to hold the transaction lock here
5972c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // because State::active is only accessed from this thread.
5982c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        current.active = front.active;
5992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6002c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        // recompute visible region
6012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        recomputeVisibleRegions = true;
6022c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6032c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6042c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    ALOGD_IF(DEBUG_RESIZE,
6052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
6062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
6072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
6082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
6092c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.w, front.active.h,
6102c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.left,
6112c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.top,
6122c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.right,
6132c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.bottom,
6142c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getWidth(),
6152c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.active.crop.getHeight(),
6162c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.w, front.requested.h,
6172c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.left,
6182c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.top,
6192c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.right,
6202c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.bottom,
6212c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getWidth(),
6222c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                            front.requested.crop.getHeight());
6232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6242c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                if (!isFixedSize) {
6262c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    if (front.active.w != bufWidth ||
6272c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        front.active.h != bufHeight) {
6284824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian                        // reject this buffer
6292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                        return true;
6302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                    }
6312c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                }
6322c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian                return false;
6332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian            }
6342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        };
6352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6372c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
6382c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian
6392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
640a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
641a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
642a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return;
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.
649e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            return;
650e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        }
651da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
6524824d40a35333182c2eb3593511b9bcbecd0a943Mathias Agopian        mRefreshPending = true;
653702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
654dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall        mNeedHwcFence = true;
655e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian        if (oldActiveBuffer == NULL) {
6562c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // the first time we receive a buffer, we need to trigger a
6572c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             // geometry invalidation.
6582c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian             mFlinger->invalidateHwcGeometry();
6592c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian         }
660702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
661702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        Rect crop(mSurfaceTexture->getCurrentCrop());
6622c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
6632c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
664702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
665702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
666702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
667702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
668702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
669702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
670702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
671702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mFlinger->invalidateHwcGeometry();
672702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
673702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
674702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
675e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufWidth  = mActiveBuffer->getWidth();
676e31564d8eb0ab67e167a888eccce20f5b4e4ef45Mathias Agopian            uint32_t bufHeight = mActiveBuffer->getHeight();
677702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
678702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
679702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                mFlinger->invalidateHwcGeometry();
680702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
681702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
682702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
683702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
684702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
685702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
686702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
687702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
688702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        // FIXME: mPostedDirtyRegion = dirty & bounds
6892c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian        const Layer::State& front(drawingState());
690702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mPostedDirtyRegion.set(front.active.w, front.active.h);
691702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
692702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
693702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
694e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
7001c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
7011c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
7024d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    Region postedRegion(mPostedDirtyRegion);
7034d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    if (!postedRegion.isEmpty()) {
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
7054d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (!visibleRegionScreen.isEmpty()) {
7064d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // The dirty region is given in the layer's coordinate space
7074d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // transform the dirty region by the surface's transformation
7084d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // and the global transformation.
7094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            const Layer::State& s(drawingState());
7104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            const Transform tr(planeTransform * s.transform);
7114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            postedRegion = tr.transform(postedRegion);
7124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian
7134d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // At this point, the dirty region is in screen space.
7144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // Make sure it's constrained by the visible region (which
7154d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // is in screen space as well).
7164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            postedRegion.andSelf(visibleRegionScreen);
7174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            outDirtyRegion.orSelf(postedRegion);
7184d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        }
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
7231b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
7241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
7251b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
726a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
727a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
7281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
7291b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
7301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
7311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
732a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
7331b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
7341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
7351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
736ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
73799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
738a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
73999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            getTransformHint(), mQueuedFrames, mRefreshPending);
7401b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
7411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
742d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
743a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mSurfaceTexture != 0) {
744a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
745bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
746d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
747d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
74882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
74982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
75082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    LayerBaseClient::dumpStats(result, buffer, SIZE);
75182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t o = mFrameLatencyOffset;
7521b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
75382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t period = hw.getRefreshPeriod();
75482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.appendFormat("%lld\n", period);
75582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<128 ; i++) {
75682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const size_t index = (o+i) % 128;
75782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_app   = mFrameStats[index].timestamp;
75882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_set   = mFrameStats[index].set;
75982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_vsync = mFrameStats[index].vsync;
76082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        result.appendFormat("%lld\t%lld\t%lld\n",
76182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_app,
76282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_vsync,
76382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_set);
76482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
76582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append("\n");
76682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
76782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
76825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats()
76925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
77025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    LayerBaseClient::clearStats();
77125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    memset(mFrameStats, 0, sizeof(mFrameStats));
77225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
77325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
774a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
775b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
776a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // TODO: should we do something special if mSecure is set?
777a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mProtectedByApp) {
778a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        // need a hardware-protected path to external video sink
779a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
780b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
7813599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
782a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return usage;
783b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
784b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
785a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianuint32_t Layer::getTransformHint() const {
786a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    uint32_t orientation = 0;
787a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
7888d91b425078083d0e4967dcd8d669d9f7196123aJamie Gennis        orientation = getPlaneOrientation();
789a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        if (orientation & Transform::ROT_INVALID) {
790a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            orientation = 0;
791a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        }
792a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    }
793a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    return orientation;
794a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
795a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
800