Layer.cpp revision 702634a4dad85cfc292618ac91eda6c00f42b7c5
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"
39a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "DisplayHardware/DisplayHardware.h"
40a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "DisplayHardware/HWComposer.h"
411f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
44a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include "SurfaceTextureLayer.h"
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE    0
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5296f0819f81293076e652792794a961543e6750d7Mathias AgopianLayer::Layer(SurfaceFlinger* flinger,
5396f0819f81293076e652792794a961543e6750d7Mathias Agopian        DisplayID display, const sp<Client>& client)
5496f0819f81293076e652792794a961543e6750d7Mathias Agopian    :   LayerBaseClient(flinger, display, 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),
66d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian        mNeedsDithering(false),
67b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        mSecure(false),
68933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian        mProtectedByApp(false)
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
70a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentCrop.makeInvalid();
71a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glGenTextures(1, &mTextureName);
72e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
73e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
74e8696a40e09b24b634214684d18526187b316a2fJamie Gennisvoid Layer::onLayerDisplayed() {
75e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (mFrameLatencyNeeded) {
7682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const DisplayHardware& hw(graphicPlane(0).displayHardware());
7782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
7882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameStats[mFrameLatencyOffset].set = systemTime();
7982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
80e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
81e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        mFrameLatencyNeeded = false;
82e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
83d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
84d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
85a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFirstRef()
8696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
87a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    LayerBaseClient::onFirstRef();
88ddc31c3e2bc6ffe66695c385d23e8ccc3c6dad06Mathias Agopian
89a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
90a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
91a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    private:
92a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<Layer> mLayer;
93a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual void onFrameAvailable() {
94a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<Layer> that(mLayer.promote());
95a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != 0) {
96a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                that->onFrameQueued();
97a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
98a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
99a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
100b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
101b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // Creates a custom BufferQueue for SurfaceTexture to use
102b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    sp<BufferQueue> bq = new SurfaceTextureLayer();
103b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture = new SurfaceTexture(mTextureName, true,
104a0db308c3d62301ae41b2e2bcf295c4ee4c7b08eMathias Agopian            GL_TEXTURE_EXTERNAL_OES, false, bq);
105b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
106b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
107a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
108a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setSynchronousMode(true);
109b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
1107f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1117f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#warning "disabling triple buffering"
112a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setBufferCountServer(2);
1137f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian#else
1147f42a9c47c5a7f40cf02032d286d6bd62f28e650Mathias Agopian    mSurfaceTexture->setBufferCountServer(3);
115303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian#endif
116b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
11796f0819f81293076e652792794a961543e6750d7Mathias Agopian
118a67932fe6864ac346e7f78b86df11cf6c5344137Mathias AgopianLayer::~Layer()
119b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{
120118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    mFlinger->postMessageAsync(
121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
12296f0819f81293076e652792794a961543e6750d7Mathias Agopian}
12396f0819f81293076e652792794a961543e6750d7Mathias Agopian
124a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianvoid Layer::onFrameQueued() {
1253d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    android_atomic_inc(&mQueuedFrames);
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger->signalLayerUpdate();
127579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian}
128579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian
129d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered
130d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian// in the purgatory list
131d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopianvoid Layer::onRemoved()
132d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian{
133dbe6486ca151d0eb1950be0aae347f0eb8ed3442Jamie Gennis    mSurfaceTexture->abandon();
13448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian}
135cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
136a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennisvoid Layer::setName(const String8& name) {
137a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    LayerBase::setName(name);
138a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis    mSurfaceTexture->setName(name);
139a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis}
140a249f2d11249ff37c48119020b797ad437ddef2cJamie Gennis
141b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamvoid Layer::validateVisibility(const Transform& globalTransform) {
142b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    LayerBase::validateVisibility(globalTransform);
143b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
144b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // This optimization allows the SurfaceTexture to bake in
145b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    // the rotation so hardware overlays can be used
146b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setTransformHint(getTransformHint());
147b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam}
148b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
149a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopiansp<ISurface> Layer::createSurface()
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
151a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    class BSurface : public BnSurface, public LayerCleaner {
152a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        wp<const Layer> mOwner;
153a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
154a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<ISurfaceTexture> res;
155a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            sp<const Layer> that( mOwner.promote() );
156a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            if (that != NULL) {
157b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam                res = that->mSurfaceTexture->getBufferQueue();
158a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            }
159a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return res;
160a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
161a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    public:
162a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        BSurface(const sp<SurfaceFlinger>& flinger,
163a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                const sp<Layer>& layer)
164a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            : LayerCleaner(flinger, layer), mOwner(layer) { }
165a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    };
166a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> sur(new BSurface(mFlinger, this));
167a1f47b90ab53af978be45b8bda16c5d084ae66e6Mathias Agopian    return sur;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
170582270d69db94286a248bd829f1ae6f910d45124Jamie Genniswp<IBinder> Layer::getSurfaceTextureBinder() const
171582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis{
172b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    return mSurfaceTexture->getBufferQueue()->asBinder();
173582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis}
174582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis
175f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            PixelFormat format, uint32_t flags)
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
178401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // this surfaces pixel format
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    PixelFormatInfo info;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = getPixelFormatInfo(format, &info);
181ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    if (err) {
182ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("unsupported pixelformat %d", format);
183ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        return err;
184ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian    }
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
186401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // the display's pixel format
187401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
188ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    uint32_t const maxSurfaceDims = min(
189ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian            hw.getMaxTextureSize(), hw.getMaxViewportDims());
190ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
191ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // never allow a surface larger than what our underlying GL implementation
192ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    // can handle.
193ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
194ff615cc7a1cceedd705b0623b058c54669b29596Mathias Agopian        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
195ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian        return BAD_VALUE;
196ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    }
197ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
198401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    PixelFormatInfo displayInfo;
199401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    getPixelFormatInfo(hw.getFormat(), &displayInfo);
200a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian    const uint32_t hwFlags = hw.getFlags();
201a4b740ed89074cda898a30eb1b029b0d3a5de1a5Mathias Agopian
202cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mFormat = format;
203eff062c49e858d0dd94a1e57f6115bc84dba103eMathias Agopian
2043330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
20516f0453fee84c6aad59fe0d1c7d36f061d46cffcGlenn Kasten    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
206a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
207a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mCurrentOpacity = getOpacityForFormat(format);
208a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
209a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferSize(w, h);
210a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    mSurfaceTexture->setDefaultBufferFormat(format);
211b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
212ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
213401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    // we use the red index
214401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
215401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
216401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian    mNeedsDithering = layerRedsize > displayRedSize;
217401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
221f15a83f5814219c167f87cb8aaea622fc8493499Jamie GennisRect Layer::computeBufferCrop() const {
222f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // Start with the SurfaceTexture's buffer crop...
223f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop;
224f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    if (!mCurrentCrop.isEmpty()) {
225f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = mCurrentCrop;
226f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else  if (mActiveBuffer != NULL){
227f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
228f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    } else {
229f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        crop = Rect(mTransformedBounds.width(), mTransformedBounds.height());
230f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
231f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
232f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // ... then reduce that in the same proportions as the window crop reduces
233f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    // the window size.
234f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    const State& s(drawingState());
23593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian    if (!s.active.crop.isEmpty()) {
236f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // Transform the window crop to match the buffer coordinate system,
237f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // which means using the inverse of the current transform set on the
238f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        // SurfaceTexture.
239f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        uint32_t invTransform = mCurrentTransform;
24093ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winWidth = s.active.w;
24193ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        int winHeight = s.active.h;
242f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
243f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
244f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
24593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winWidth = s.active.h;
24693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian            winHeight = s.active.w;
247f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
24893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        Rect winCrop = s.active.crop.transform(invTransform,
24993ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                s.active.w, s.active.h);
250f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
251f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float xScale = float(crop.width()) / float(winWidth);
252f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        float yScale = float(crop.height()) / float(winHeight);
25393ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.left += int(ceilf(float(winCrop.left) * xScale));
25493ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.top += int(ceilf(float(winCrop.top) * yScale));
25593ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
25693ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
257f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    }
258f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
259f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    return crop;
260f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis}
261f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis
262a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopianvoid Layer::setGeometry(hwc_layer_t* hwcl)
263a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
264a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    LayerBaseClient::setGeometry(hwcl);
265a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian
266a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    hwcl->flags &= ~HWC_SKIP_LAYER;
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) {
271a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
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) {
291a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwcl->flags = HWC_SKIP_LAYER;
292a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian    } else {
293a537c0f42e8077baafcbc65844adf1ec8397c040Mathias Agopian        hwcl->transform = finalTransform;
294a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
295f345069099a13f0c2dd91f1fa92786643e4becb0Mathias Agopian
296f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect crop = computeBufferCrop();
297f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    hwcl->sourceCrop.left   = crop.left;
298f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    hwcl->sourceCrop.top    = crop.top;
299f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    hwcl->sourceCrop.right  = crop.right;
300f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    hwcl->sourceCrop.bottom = crop.bottom;
301a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
302a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
303c7f3381c3b2945e441747130eae88214435d0819Mathias Agopianvoid Layer::setPerFrameData(hwc_layer_t* hwcl) {
304c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian    const sp<GraphicBuffer>& buffer(mActiveBuffer);
305c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian    if (buffer == NULL) {
306c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian        // this can happen if the client never drew into this layer yet,
307c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian        // or if we ran out of memory. In that case, don't let
308c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian        // HWC handle it.
309c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian        hwcl->flags |= HWC_SKIP_LAYER;
310c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian        hwcl->handle = NULL;
311c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian    } else {
312c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian        hwcl->handle = buffer->handle;
313c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian    }
314c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian}
315c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
3191c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
320a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (CC_UNLIKELY(mActiveBuffer == 0)) {
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // the texture has not been created yet, this Layer has
322179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // in fact never been drawn into. This happens frequently with
323179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // SurfaceView because the WindowManager can't know when the client
324179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // has drawn the first time.
325179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
326179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // If there is nothing under us, we paint the screen in black, otherwise
327179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // we just skip this update.
328179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian
329179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // figure out if there is something below us
330179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region under;
331f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian        const SurfaceFlinger::LayerVector& drawingLayers(
332f7ae69d4bd292110da976c8ae766a8ef083d731fMathias Agopian                mFlinger->mDrawingState.layersSortedByZ);
333179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        const size_t count = drawingLayers.size();
334179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
335179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            const sp<LayerBase>& layer(drawingLayers[i]);
336179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            if (layer.get() == static_cast<LayerBase const*>(this))
337179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian                break;
338179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian            under.orSelf(layer->visibleRegionScreen);
339179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
340179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        // if not everything below us is covered, we plug the holes!
341179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        Region holes(clip.subtract(under));
342179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        if (!holes.isEmpty()) {
3430a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian            clearWithOpenGL(holes, 0, 0, 0, 1);
344179169e88e05261196b76d7ddf94aa870aafaf9aMathias Agopian        }
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
347a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
3489575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    if (!isProtected()) {
349cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // TODO: we could be more subtle with isFixedSize()
350cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
351cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
352cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Query the texture matrix given our current filtering mode.
353cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        float textureMatrix[16];
354cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->setFilteringEnabled(useFiltering);
355cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        mSurfaceTexture->getTransformMatrix(textureMatrix);
356cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis
357cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        // Set things up for texturing.
358c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
359c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        GLenum filter = GL_NEAREST;
360cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        if (useFiltering) {
361c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian            filter = GL_LINEAR;
3629575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        }
363c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
364c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
3659575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
366cbb1a95819ec302ae15e4a1162a8b1349ae5c33eJamie Gennis        glLoadMatrixf(textureMatrix);
3679575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
368c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_2D);
3694c4163b53e262ff9cc10c819321d4ae03c2d7d46Xavier Ducrohet        glEnable(GL_TEXTURE_EXTERNAL_OES);
370a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    } else {
371c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
3729575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_TEXTURE);
3739575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glLoadIdentity();
3749575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        glMatrixMode(GL_MODELVIEW);
375c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glDisable(GL_TEXTURE_EXTERNAL_OES);
376c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian        glEnable(GL_TEXTURE_2D);
377a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    }
378a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
379a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    drawWithOpenGL(clip);
380a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
381c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
382c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
385ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// As documented in libhardware header, formats in the range
386ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// 0x100 - 0x1FF are specific to the HAL implementation, and
387ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// are known to have no alpha channel
388ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// TODO: move definition for device-specific range into
389ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold// hardware.h, instead of using hard-coded values here.
390ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
391ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
392a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::getOpacityForFormat(uint32_t format)
393ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold{
394a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
395a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return true;
396ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold    }
397a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    PixelFormatInfo info;
398a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
399a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // in case of error (unknown format), we assume no blending
400a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return (err || info.h_alpha <= info.l_alpha);
401ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold}
402ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
403ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
404a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isOpaque() const
405a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian{
406a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if we don't have a buffer yet, we're translucent regardless of the
407a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // layer's opaque flag.
408db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    if (mActiveBuffer == 0) {
409a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        return false;
410db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis    }
411a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
412a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // if the layer has the opaque flag, then we're always opaque,
413a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // otherwise we use the current buffer's format.
414a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return mOpaqueLayer || mCurrentOpacity;
415a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian}
416a7f669256f93a593c723f05784ef04d3c7d052bbMathias Agopian
4177a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennisbool Layer::isProtected() const
4187a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis{
419a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
4207a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis    return (activeBuffer != 0) &&
4217a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4227a4d0dfd43558c299e6af6c4910ef76db9db3172Jamie Gennis}
423b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags)
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
4261c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
4271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& front(drawingState());
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Layer::State& temp(currentState());
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43105cec9d1275fd939c2d1aec235dca2bdb8edef63Mathias Agopian    const bool sizeChanged = (temp.requested.w != front.active.w) ||
43205cec9d1275fd939c2d1aec235dca2bdb8edef63Mathias Agopian                             (temp.requested.h != front.active.h);
433a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
434a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian    if (sizeChanged) {
435cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // the size changed, we need to ask our client to request a new buffer
4369d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block        ALOGD_IF(DEBUG_RESIZE,
437419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
438419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
439419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
440419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
441419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
442419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                this, mCurrentScalingMode,
443419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.w, temp.active.h,
444419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.left,
445419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.top,
446419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.right,
447419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.bottom,
448419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getWidth(),
449419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.active.crop.getHeight(),
450419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                temp.requested.w, temp.requested.h,
451b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.left,
452b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.top,
453b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.right,
454b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.bottom,
455b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getWidth(),
456b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.crop.getHeight(),
457419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.w, front.active.h,
458419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.left,
459419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.top,
460419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.right,
461419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.bottom,
462419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getWidth(),
463419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.active.crop.getHeight(),
464419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.w, front.requested.h,
465b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.left,
466b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.top,
467b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.right,
468b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.bottom,
469b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                front.requested.crop.getWidth(),
470419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                front.requested.crop.getHeight());
471a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
472a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        if (!isFixedSize()) {
473a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian            // this will make sure LayerBase::doTransaction doesn't update
474b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian            // the drawing state's geometry
47505cec9d1275fd939c2d1aec235dca2bdb8edef63Mathias Agopian            flags |= eDontUpdateGeometryState;
476a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian        }
4772a0d5b608447a880beff5149805425f02691442bJamie Gennis
4782a0d5b608447a880beff5149805425f02691442bJamie Gennis        // record the new size, form this point on, when the client request
4792a0d5b608447a880beff5149805425f02691442bJamie Gennis        // a buffer, it'll get the new size.
480b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian        mSurfaceTexture->setDefaultBufferSize(
481b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian                temp.requested.w, temp.requested.h);
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
483cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return LayerBase::doTransaction(flags);
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
487a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isFixedSize() const {
488933389f75814bb62e8153528f9cff2cb329b77dfMathias Agopian    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
489a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian}
490a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
491a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianbool Layer::isCropped() const {
492a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return !mCurrentCrop.isEmpty();
493a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian}
494a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling...
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopianbool Layer::onPreComposition() {
5004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    mRefreshPending = false;
5014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    return mQueuedFrames > 0;
50299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
50399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
5061c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
5071c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
5083d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis    if (mQueuedFrames > 0) {
50999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
51099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // if we've already called updateTexImage() without going through
51199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // a composition step, we have to skip this layer at this point
51299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // because we cannot call updateTeximage() without a corresponding
51399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // compositionComplete() call.
51499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        // we'll trigger an update in onPreComposition().
5154d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (mRefreshPending) {
5164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            mPostedDirtyRegion.clear();
51799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            return;
51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
5194d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        mRefreshPending = true;
52099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
521351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // Capture the old state of the layer for comparisons later
522db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis        const bool oldOpacity = isOpaque();
523351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
524db5230f4441fa8f120f15bdd6fcfc6e75d9c27d0Jamie Gennis
5253d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        // signal another event if we have more frames pending
5263d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        if (android_atomic_dec(&mQueuedFrames) > 1) {
52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mFlinger->signalLayerUpdate();
5283d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis        }
5293d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis
530a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
531a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            // something happened!
532a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            recomputeVisibleRegions = true;
533a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            return;
534a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        }
535d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
536351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        // update the active buffer
537351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
538da9584dc295cc5e6d0b49a97c1e45159249d650bMathias Agopian
539351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        uint32_t bufWidth  = mActiveBuffer->getWidth();
540351a513b12622781de9580b3c96fd0a8578b563bJamie Gennis        uint32_t bufHeight = mActiveBuffer->getHeight();
541702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
542702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
543c7f3381c3b2945e441747130eae88214435d0819Mathias Agopian
544702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        // check that we received a buffer of the right size
545702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        // (Take the buffer's orientation into account)
546702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (mCurrentTransform & Transform::ROT_90) {
547702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            swap(bufWidth, bufHeight);
548ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold        }
549ac45e6bff1b41acd35c981291b37b23f8e083ceeEric Hassold
550a402c4c9913cfbc6c3da21719c57a93a11f091f0Jamie Gennis        // update the layer size if needed
551d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        const Layer::State& front(drawingState());
552a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
553b30c415539813b96a831b75d07f3d12aef1aeab7Mathias Agopian        if (front.active != front.requested) {
554702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            bool isFixedSize = scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
55597c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian
556702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (isFixedSize ||
55793ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                    (bufWidth == front.requested.w &&
55893ffb86b909005bbee4993fc9053f017466311c7Mathias Agopian                    bufHeight == front.requested.h))
559d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian            {
560d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // Here we pretend the transaction happened by updating the
561d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // current and drawing states. Drawing state is only accessed
562d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // in this thread, no need to have it locked
563419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                Layer::State& editFront(mDrawingState);
564419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                editFront.active = front.requested;
565419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian
566419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                // We also need to update the current state so that
567419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                // we don't end-up overwriting the drawing state with
568419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                // this stale current state during the next transaction
569419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                //
570419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                // NOTE: We don't need to hold the transaction lock here
571419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                // because State::active is only accessed from this thread.
572419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                Layer::State& editCurrent(currentState());
573419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                editCurrent.active = front.active;
574d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian
575d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                // recompute visible region
576d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian                recomputeVisibleRegions = true;
57797c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian            }
5783fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian
5799d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block            ALOGD_IF(DEBUG_RESIZE,
580419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
581419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
582419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
583702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                    this, bufWidth, bufHeight, transform, scalingMode,
584419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.w, front.active.h,
585419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.crop.left,
586419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.crop.top,
587419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.crop.right,
588419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.crop.bottom,
589419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.crop.getWidth(),
590419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.active.crop.getHeight(),
591419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.w, front.requested.h,
592419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.crop.left,
593419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.crop.top,
594419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.crop.right,
595419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.crop.bottom,
596419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.crop.getWidth(),
597419e196e639c8adb875da2765abcef95017b6d4aMathias Agopian                    front.requested.crop.getHeight());
598d343e3d5e3177806205b9452b0b43907e28afd9aMathias Agopian        }
599702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
600702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mFrameLatencyNeeded = true;
601702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
602702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer == NULL && mActiveBuffer != NULL) {
603702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            // the first time we receive a buffer, we need to trigger a
604702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            // geometry invalidation.
605702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mFlinger->invalidateHwcGeometry();
606702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
607702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
608702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
609702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        Rect crop(mSurfaceTexture->getCurrentCrop());
610702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if ((crop != mCurrentCrop) ||
611702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (transform != mCurrentTransform) ||
612702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            (scalingMode != mCurrentScalingMode))
613702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        {
614702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentCrop = crop;
615702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentTransform = transform;
616702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mCurrentScalingMode = scalingMode;
617702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            mFlinger->invalidateHwcGeometry();
618702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
619702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
620702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldActiveBuffer != NULL) {
621702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
622702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                bufHeight != uint32_t(oldActiveBuffer->height)) {
623702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian                mFlinger->invalidateHwcGeometry();
624702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            }
625702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
626702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
627702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
628702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        if (oldOpacity != isOpaque()) {
629702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian            recomputeVisibleRegions = true;
630702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        }
631702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
632702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        // FIXME: mPostedDirtyRegion = dirty & bounds
633702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        mPostedDirtyRegion.set(front.active.w, front.active.h);
634702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian
635702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
636702634a4dad85cfc292618ac91eda6c00f42b7c5Mathias Agopian        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
637e700501d0e888ead9ac6456c0a6fd74d634aa5fbMathias Agopian    }
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip(
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const Transform& planeTransform, Region& outDirtyRegion)
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
6431c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
6441c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
6454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    Region postedRegion(mPostedDirtyRegion);
6464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian    if (!postedRegion.isEmpty()) {
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPostedDirtyRegion.clear();
6484d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        if (!visibleRegionScreen.isEmpty()) {
6494d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // The dirty region is given in the layer's coordinate space
6504d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // transform the dirty region by the surface's transformation
6514d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // and the global transformation.
6524d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            const Layer::State& s(drawingState());
6534d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            const Transform tr(planeTransform * s.transform);
6544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            postedRegion = tr.transform(postedRegion);
6554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian
6564d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // At this point, the dirty region is in screen space.
6574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // Make sure it's constrained by the visible region (which
6584d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            // is in screen space as well).
6594d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            postedRegion.andSelf(visibleRegionScreen);
6604d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            outDirtyRegion.orSelf(postedRegion);
6614d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian        }
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopianvoid Layer::dump(String8& result, char* buffer, size_t SIZE) const
6661b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
6671b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    LayerBaseClient::dump(result, buffer, SIZE);
6681b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
669a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<const GraphicBuffer> buf0(mActiveBuffer);
670a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    uint32_t w0=0, h0=0, s0=0, f0=0;
6711b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    if (buf0 != 0) {
6721b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        w0 = buf0->getWidth();
6731b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        h0 = buf0->getHeight();
6741b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian        s0 = buf0->getStride();
675a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        f0 = buf0->format;
6761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    }
6771b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    snprintf(buffer, SIZE,
6781b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian            "      "
679ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
68099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
681a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            mFormat, w0, h0, s0,f0,
68299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            getTransformHint(), mQueuedFrames, mRefreshPending);
6831b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
6841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian    result.append(buffer);
685d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
686a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mSurfaceTexture != 0) {
687a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
688bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian    }
689d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian}
690d606de6bb6877dc4ab93ec0be0c6bda4a8ee1ce8Mathias Agopian
69182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
69282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
69382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    LayerBaseClient::dumpStats(result, buffer, SIZE);
69482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t o = mFrameLatencyOffset;
69582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const DisplayHardware& hw(graphicPlane(0).displayHardware());
69682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t period = hw.getRefreshPeriod();
69782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.appendFormat("%lld\n", period);
69882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<128 ; i++) {
69982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const size_t index = (o+i) % 128;
70082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_app   = mFrameStats[index].timestamp;
70182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_set   = mFrameStats[index].set;
70282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const nsecs_t time_vsync = mFrameStats[index].vsync;
70382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        result.appendFormat("%lld\t%lld\t%lld\n",
70482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_app,
70582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_vsync,
70682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                time_set);
70782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
70882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append("\n");
70982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
71082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
71125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid Layer::clearStats()
71225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
71325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    LayerBaseClient::clearStats();
71425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    memset(mFrameStats, 0, sizeof(mFrameStats));
71525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
71625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
717a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianuint32_t Layer::getEffectiveUsage(uint32_t usage) const
718b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{
719a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    // TODO: should we do something special if mSecure is set?
720a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (mProtectedByApp) {
721a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        // need a hardware-protected path to external video sink
722a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        usage |= GraphicBuffer::USAGE_PROTECTED;
723b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian    }
7243599bf2c0727bc33e8136f5163eee6f398545e05Jamie Gennis    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
725a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return usage;
726b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian}
727b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian
728a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopianuint32_t Layer::getTransformHint() const {
729a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    uint32_t orientation = 0;
730a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    if (!mFlinger->mDebugDisableTransformHint) {
7318d91b425078083d0e4967dcd8d669d9f7196123aJamie Gennis        orientation = getPlaneOrientation();
732a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        if (orientation & Transform::ROT_INVALID) {
733a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            orientation = 0;
734a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        }
735a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    }
736a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian    return orientation;
737a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian}
738a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
743