Layer.cpp revision ef19414bd8b77a26f5751f3845be79025a8263fe
16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 2007 The Android Open Source Project
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * you may not use this file except in compliance with the License.
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * You may obtain a copy of the License at
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *      http://www.apache.org/licenses/LICENSE-2.0
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Unless required by applicable law or agreed to in writing, software
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * See the License for the specific language governing permissions and
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * limitations under the License.
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ATRACE_TAG ATRACE_TAG_GRAPHICS
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdlib.h>
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdint.h>
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <sys/types.h>
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <math.h>
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <cutils/compiler.h>
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <cutils/native_handle.h>
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <cutils/properties.h>
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/Errors.h>
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/Log.h>
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/StopWatch.h>
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <utils/Trace.h>
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <ui/GraphicBuffer.h>
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <ui/PixelFormat.h>
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <gui/Surface.h>
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "clz.h"
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "DisplayHardware/DisplayHardware.h"
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "DisplayHardware/HWComposer.h"
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "GLExtensions.h"
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "Layer.h"
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "SurfaceFlinger.h"
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "SurfaceTextureLayer.h"
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DEBUG_RESIZE    0
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace android {
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ---------------------------------------------------------------------------
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgLayer::Layer(SurfaceFlinger* flinger,
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        DisplayID display, const sp<Client>& client)
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    :   LayerBaseClient(flinger, display, client),
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mTextureName(-1U),
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mQueuedFrames(0),
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mCurrentTransform(0),
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mCurrentOpacity(true),
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mRefreshPending(false),
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameLatencyNeeded(false),
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameLatencyOffset(0),
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFormat(PIXEL_FORMAT_NONE),
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mGLExtensions(GLExtensions::getInstance()),
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mOpaqueLayer(true),
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mNeedsDithering(false),
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mSecure(false),
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mProtectedByApp(false)
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mCurrentCrop.makeInvalid();
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    glGenTextures(1, &mTextureName);
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) {
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (layer) {
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mFrameLatencyNeeded) {
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const DisplayHardware& hw(graphicPlane(0).displayHardware());
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameStats[mFrameLatencyOffset].set = systemTime();
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mFrameLatencyNeeded = false;
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onFirstRef()
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    LayerBaseClient::onFirstRef();
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    private:
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        wp<Layer> mLayer;
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        virtual void onFrameAvailable() {
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            sp<Layer> that(mLayer.promote());
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (that != 0) {
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                that->onFrameQueued();
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Creates a custom BufferQueue for SurfaceTexture to use
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sp<BufferQueue> bq = new SurfaceTextureLayer();
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture = new SurfaceTexture(mTextureName, true,
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            GL_TEXTURE_EXTERNAL_OES, false, bq);
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setSynchronousMode(true);
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#warning "disabling triple buffering"
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setBufferCountServer(2);
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setBufferCountServer(3);
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgLayer::~Layer()
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mFlinger->postMessageAsync(
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onFrameQueued() {
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    android_atomic_inc(&mQueuedFrames);
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mFlinger->signalLayerUpdate();
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// called with SurfaceFlinger::mStateLock as soon as the layer is entered
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// in the purgatory list
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onRemoved()
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->abandon();
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::setName(const String8& name) {
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    LayerBase::setName(name);
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setName(name);
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::validateVisibility(const Transform& globalTransform) {
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    LayerBase::validateVisibility(globalTransform);
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // This optimization allows the SurfaceTexture to bake in
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // the rotation so hardware overlays can be used
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setTransformHint(getTransformHint());
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgsp<ISurface> Layer::createSurface()
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    class BSurface : public BnSurface, public LayerCleaner {
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        wp<const Layer> mOwner;
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            sp<ISurfaceTexture> res;
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            sp<const Layer> that( mOwner.promote() );
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (that != NULL) {
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                res = that->mSurfaceTexture->getBufferQueue();
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return res;
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    public:
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        BSurface(const sp<SurfaceFlinger>& flinger,
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                const sp<Layer>& layer)
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            : LayerCleaner(flinger, layer), mOwner(layer) { }
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sp<ISurface> sur(new BSurface(mFlinger, this));
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return sur;
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgwp<IBinder> Layer::getSurfaceTextureBinder() const
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return mSurfaceTexture->getBufferQueue()->asBinder();
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatus_t Layer::setBuffers( uint32_t w, uint32_t h,
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            PixelFormat format, uint32_t flags)
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // this surfaces pixel format
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    PixelFormatInfo info;
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    status_t err = getPixelFormatInfo(format, &info);
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (err) {
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ALOGE("unsupported pixelformat %d", format);
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return err;
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // the display's pixel format
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const DisplayHardware& hw(graphicPlane(0).displayHardware());
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t const maxSurfaceDims = min(
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            hw.getMaxTextureSize(), hw.getMaxViewportDims());
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // never allow a surface larger than what our underlying GL implementation
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // can handle.
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return BAD_VALUE;
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    PixelFormatInfo displayInfo;
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    getPixelFormatInfo(hw.getFormat(), &displayInfo);
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint32_t hwFlags = hw.getFlags();
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mFormat = format;
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mCurrentOpacity = getOpacityForFormat(format);
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setDefaultBufferSize(w, h);
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setDefaultBufferFormat(format);
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // we use the red index
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mNeedsDithering = layerRedsize > displayRedSize;
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NO_ERROR;
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgRect Layer::computeBufferCrop() const {
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Start with the SurfaceTexture's buffer crop...
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Rect crop;
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!mCurrentCrop.isEmpty()) {
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop = mCurrentCrop;
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else  if (mActiveBuffer != NULL){
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop = Rect(mTransformedBounds.width(), mTransformedBounds.height());
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // ... then reduce that in the same proportions as the window crop reduces
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // the window size.
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const State& s(drawingState());
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!s.active.crop.isEmpty()) {
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Transform the window crop to match the buffer coordinate system,
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // which means using the inverse of the current transform set on the
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // SurfaceTexture.
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uint32_t invTransform = mCurrentTransform;
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int winWidth = s.active.w;
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int winHeight = s.active.h;
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            winWidth = s.active.h;
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            winHeight = s.active.w;
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Rect winCrop = s.active.crop.transform(invTransform,
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                s.active.w, s.active.h);
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        float xScale = float(crop.width()) / float(winWidth);
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        float yScale = float(crop.height()) / float(winHeight);
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop.left += int(ceilf(float(winCrop.left) * xScale));
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop.top += int(ceilf(float(winCrop.top) * yScale));
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return crop;
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    LayerBaseClient::setGeometry(layer);
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // enable this layer
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    layer.setSkip(false);
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // we can't do alpha-fade with the hwc HAL
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const State& s(drawingState());
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (s.alpha < 0xFF) {
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        layer.setSkip(true);
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Transformations are applied in this order:
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 1) buffer orientation/flip/mirror
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 2) state transformation (window manager)
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 3) layer orientation (screen orientation)
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * mTransform is already the composition of (2) and (3)
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * (NOTE: the matrices are multiplied in reverse order)
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Transform bufferOrientation(mCurrentTransform);
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Transform tr(mTransform * bufferOrientation);
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // this gives us only the "orientation" component of the transform
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint32_t finalTransform = tr.getOrientation();
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // we can only handle simple transformation
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (finalTransform & Transform::ROT_INVALID) {
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        layer.setSkip(true);
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        layer.setTransform(finalTransform);
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    layer.setCrop(computeBufferCrop());
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const sp<GraphicBuffer>& buffer(mActiveBuffer);
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // NOTE: buffer can be NULL if the client never drew into this
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // layer yet, or if we ran out of memory
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    layer.setBuffer(buffer);
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::onDraw(const Region& clip) const
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ATRACE_CALL();
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (CC_UNLIKELY(mActiveBuffer == 0)) {
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // the texture has not been created yet, this Layer has
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // in fact never been drawn into. This happens frequently with
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // SurfaceView because the WindowManager can't know when the client
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // has drawn the first time.
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // If there is nothing under us, we paint the screen in black, otherwise
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // we just skip this update.
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // figure out if there is something below us
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Region under;
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const SurfaceFlinger::LayerVector& drawingLayers(
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                mFlinger->mDrawingState.layersSortedByZ);
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const size_t count = drawingLayers.size();
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (size_t i=0 ; i<count ; ++i) {
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const sp<LayerBase>& layer(drawingLayers[i]);
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (layer.get() == static_cast<LayerBase const*>(this))
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            under.orSelf(layer->visibleRegionScreen);
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // if not everything below us is covered, we plug the holes!
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Region holes(clip.subtract(under));
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (!holes.isEmpty()) {
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            clearWithOpenGL(holes, 0, 0, 0, 1);
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!isProtected()) {
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // TODO: we could be more subtle with isFixedSize()
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Query the texture matrix given our current filtering mode.
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        float textureMatrix[16];
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mSurfaceTexture->setFilteringEnabled(useFiltering);
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mSurfaceTexture->getTransformMatrix(textureMatrix);
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Set things up for texturing.
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        GLenum filter = GL_NEAREST;
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (useFiltering) {
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            filter = GL_LINEAR;
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glMatrixMode(GL_TEXTURE);
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glLoadMatrixf(textureMatrix);
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glMatrixMode(GL_MODELVIEW);
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glDisable(GL_TEXTURE_2D);
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glEnable(GL_TEXTURE_EXTERNAL_OES);
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glMatrixMode(GL_TEXTURE);
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glLoadIdentity();
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glMatrixMode(GL_MODELVIEW);
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glDisable(GL_TEXTURE_EXTERNAL_OES);
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        glEnable(GL_TEXTURE_2D);
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    drawWithOpenGL(clip);
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    glDisable(GL_TEXTURE_EXTERNAL_OES);
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    glDisable(GL_TEXTURE_2D);
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// As documented in libhardware header, formats in the range
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 0x100 - 0x1FF are specific to the HAL implementation, and
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// are known to have no alpha channel
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TODO: move definition for device-specific range into
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// hardware.h, instead of using hard-coded values here.
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::getOpacityForFormat(uint32_t format)
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return true;
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    PixelFormatInfo info;
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // in case of error (unknown format), we assume no blending
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (err || info.h_alpha <= info.l_alpha);
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isOpaque() const
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // if we don't have a buffer yet, we're translucent regardless of the
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // layer's opaque flag.
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mActiveBuffer == 0) {
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return false;
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // if the layer has the opaque flag, then we're always opaque,
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // otherwise we use the current buffer's format.
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return mOpaqueLayer || mCurrentOpacity;
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isProtected() const
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (activeBuffer != 0) &&
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguint32_t Layer::doTransaction(uint32_t flags)
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ATRACE_CALL();
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Layer::State& front(drawingState());
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Layer::State& temp(currentState());
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const bool sizeChanged = (temp.requested.w != front.requested.w) ||
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             (temp.requested.h != front.requested.h);
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (sizeChanged) {
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // the size changed, we need to ask our client to request a new buffer
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ALOGD_IF(DEBUG_RESIZE,
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                this, mCurrentScalingMode,
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.w, temp.active.h,
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.crop.left,
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.crop.top,
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.crop.right,
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.crop.bottom,
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.crop.getWidth(),
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.active.crop.getHeight(),
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.w, temp.requested.h,
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.crop.left,
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.crop.top,
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.crop.right,
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.crop.bottom,
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.crop.getWidth(),
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.crop.getHeight(),
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.w, front.active.h,
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.crop.left,
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.crop.top,
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.crop.right,
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.crop.bottom,
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.crop.getWidth(),
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.active.crop.getHeight(),
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.w, front.requested.h,
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.crop.left,
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.crop.top,
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.crop.right,
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.crop.bottom,
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.crop.getWidth(),
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                front.requested.crop.getHeight());
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // record the new size, form this point on, when the client request
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // a buffer, it'll get the new size.
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        mSurfaceTexture->setDefaultBufferSize(
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                temp.requested.w, temp.requested.h);
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!isFixedSize()) {
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const bool resizePending = (temp.requested.w != temp.active.w) ||
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   (temp.requested.h != temp.active.h);
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (resizePending) {
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // don't let LayerBase::doTransaction update the drawing state
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // if we have a pending resize, unless we are in fixed-size mode.
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // the drawing state will be updated only once we receive a buffer
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // with the correct size.
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            //
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // in particular, we want to make sure the clip (which is part
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // of the geometry state) is latched together with the size but is
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // latched immediately when no resizing is involved.
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            flags |= eDontUpdateGeometryState;
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return LayerBase::doTransaction(flags);
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isFixedSize() const {
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::isCropped() const {
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return !mCurrentCrop.isEmpty();
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ----------------------------------------------------------------------------
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// pageflip handling...
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ----------------------------------------------------------------------------
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool Layer::onPreComposition() {
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mRefreshPending = false;
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return mQueuedFrames > 0;
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Layer::lockPageFlip(bool& recomputeVisibleRegions)
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ATRACE_CALL();
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mQueuedFrames > 0) {
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // if we've already called updateTexImage() without going through
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // a composition step, we have to skip this layer at this point
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // because we cannot call updateTeximage() without a corresponding
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // compositionComplete() call.
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // we'll trigger an update in onPreComposition().
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (mRefreshPending) {
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            mPostedDirtyRegion.clear();
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return;
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Capture the old state of the layer for comparisons later
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const bool oldOpacity = isOpaque();
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // signal another event if we have more frames pending
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (android_atomic_dec(&mQueuedFrames) > 1) {
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            mFlinger->signalLayerUpdate();
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        struct Reject : public SurfaceTexture::BufferRejecter {
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            Layer::State& front;
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            Layer::State& current;
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            bool& recomputeVisibleRegions;
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            Reject(Layer::State& front, Layer::State& current,
541                    bool& recomputeVisibleRegions)
542                : front(front), current(current),
543                  recomputeVisibleRegions(recomputeVisibleRegions) {
544            }
545
546            virtual bool reject(const sp<GraphicBuffer>& buf,
547                    const BufferQueue::BufferItem& item) {
548                if (buf == NULL) {
549                    return false;
550                }
551
552                uint32_t bufWidth  = buf->getWidth();
553                uint32_t bufHeight = buf->getHeight();
554
555                // check that we received a buffer of the right size
556                // (Take the buffer's orientation into account)
557                if (item.mTransform & Transform::ROT_90) {
558                    swap(bufWidth, bufHeight);
559                }
560
561
562                bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
563                if (front.active != front.requested) {
564
565                    if (isFixedSize ||
566                            (bufWidth == front.requested.w &&
567                             bufHeight == front.requested.h))
568                    {
569                        // Here we pretend the transaction happened by updating the
570                        // current and drawing states. Drawing state is only accessed
571                        // in this thread, no need to have it locked
572                        front.active = front.requested;
573
574                        // We also need to update the current state so that
575                        // we don't end-up overwriting the drawing state with
576                        // this stale current state during the next transaction
577                        //
578                        // NOTE: We don't need to hold the transaction lock here
579                        // because State::active is only accessed from this thread.
580                        current.active = front.active;
581
582                        // recompute visible region
583                        recomputeVisibleRegions = true;
584                    }
585
586                    ALOGD_IF(DEBUG_RESIZE,
587                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
588                            "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
589                            "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
590                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
591                            front.active.w, front.active.h,
592                            front.active.crop.left,
593                            front.active.crop.top,
594                            front.active.crop.right,
595                            front.active.crop.bottom,
596                            front.active.crop.getWidth(),
597                            front.active.crop.getHeight(),
598                            front.requested.w, front.requested.h,
599                            front.requested.crop.left,
600                            front.requested.crop.top,
601                            front.requested.crop.right,
602                            front.requested.crop.bottom,
603                            front.requested.crop.getWidth(),
604                            front.requested.crop.getHeight());
605                }
606
607                if (!isFixedSize) {
608                    if (front.active.w != bufWidth ||
609                        front.active.h != bufHeight) {
610                        // reject this buffer
611                        return true;
612                    }
613                }
614                return false;
615            }
616        };
617
618
619        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
620
621        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
622            // something happened!
623            recomputeVisibleRegions = true;
624            return;
625        }
626
627        // update the active buffer
628        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
629        if (mActiveBuffer == NULL) {
630            // this can only happen if the very first buffer was rejected.
631            return;
632        }
633
634        mRefreshPending = true;
635        mFrameLatencyNeeded = true;
636        if (oldActiveBuffer == NULL) {
637             // the first time we receive a buffer, we need to trigger a
638             // geometry invalidation.
639             mFlinger->invalidateHwcGeometry();
640         }
641
642        Rect crop(mSurfaceTexture->getCurrentCrop());
643        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
644        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
645        if ((crop != mCurrentCrop) ||
646            (transform != mCurrentTransform) ||
647            (scalingMode != mCurrentScalingMode))
648        {
649            mCurrentCrop = crop;
650            mCurrentTransform = transform;
651            mCurrentScalingMode = scalingMode;
652            mFlinger->invalidateHwcGeometry();
653        }
654
655        if (oldActiveBuffer != NULL) {
656            uint32_t bufWidth  = mActiveBuffer->getWidth();
657            uint32_t bufHeight = mActiveBuffer->getHeight();
658            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
659                bufHeight != uint32_t(oldActiveBuffer->height)) {
660                mFlinger->invalidateHwcGeometry();
661            }
662        }
663
664        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
665        if (oldOpacity != isOpaque()) {
666            recomputeVisibleRegions = true;
667        }
668
669        // FIXME: mPostedDirtyRegion = dirty & bounds
670        const Layer::State& front(drawingState());
671        mPostedDirtyRegion.set(front.active.w, front.active.h);
672
673        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
674        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
675    }
676}
677
678void Layer::unlockPageFlip(
679        const Transform& planeTransform, Region& outDirtyRegion)
680{
681    ATRACE_CALL();
682
683    Region postedRegion(mPostedDirtyRegion);
684    if (!postedRegion.isEmpty()) {
685        mPostedDirtyRegion.clear();
686        if (!visibleRegionScreen.isEmpty()) {
687            // The dirty region is given in the layer's coordinate space
688            // transform the dirty region by the surface's transformation
689            // and the global transformation.
690            const Layer::State& s(drawingState());
691            const Transform tr(planeTransform * s.transform);
692            postedRegion = tr.transform(postedRegion);
693
694            // At this point, the dirty region is in screen space.
695            // Make sure it's constrained by the visible region (which
696            // is in screen space as well).
697            postedRegion.andSelf(visibleRegionScreen);
698            outDirtyRegion.orSelf(postedRegion);
699        }
700    }
701}
702
703void Layer::dump(String8& result, char* buffer, size_t SIZE) const
704{
705    LayerBaseClient::dump(result, buffer, SIZE);
706
707    sp<const GraphicBuffer> buf0(mActiveBuffer);
708    uint32_t w0=0, h0=0, s0=0, f0=0;
709    if (buf0 != 0) {
710        w0 = buf0->getWidth();
711        h0 = buf0->getHeight();
712        s0 = buf0->getStride();
713        f0 = buf0->format;
714    }
715    snprintf(buffer, SIZE,
716            "      "
717            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
718            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
719            mFormat, w0, h0, s0,f0,
720            getTransformHint(), mQueuedFrames, mRefreshPending);
721
722    result.append(buffer);
723
724    if (mSurfaceTexture != 0) {
725        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
726    }
727}
728
729void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
730{
731    LayerBaseClient::dumpStats(result, buffer, SIZE);
732    const size_t o = mFrameLatencyOffset;
733    const DisplayHardware& hw(graphicPlane(0).displayHardware());
734    const nsecs_t period = hw.getRefreshPeriod();
735    result.appendFormat("%lld\n", period);
736    for (size_t i=0 ; i<128 ; i++) {
737        const size_t index = (o+i) % 128;
738        const nsecs_t time_app   = mFrameStats[index].timestamp;
739        const nsecs_t time_set   = mFrameStats[index].set;
740        const nsecs_t time_vsync = mFrameStats[index].vsync;
741        result.appendFormat("%lld\t%lld\t%lld\n",
742                time_app,
743                time_vsync,
744                time_set);
745    }
746    result.append("\n");
747}
748
749void Layer::clearStats()
750{
751    LayerBaseClient::clearStats();
752    memset(mFrameStats, 0, sizeof(mFrameStats));
753}
754
755uint32_t Layer::getEffectiveUsage(uint32_t usage) const
756{
757    // TODO: should we do something special if mSecure is set?
758    if (mProtectedByApp) {
759        // need a hardware-protected path to external video sink
760        usage |= GraphicBuffer::USAGE_PROTECTED;
761    }
762    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
763    return usage;
764}
765
766uint32_t Layer::getTransformHint() const {
767    uint32_t orientation = 0;
768    if (!mFlinger->mDebugDisableTransformHint) {
769        orientation = getPlaneOrientation();
770        if (orientation & Transform::ROT_INVALID) {
771            orientation = 0;
772        }
773    }
774    return orientation;
775}
776
777// ---------------------------------------------------------------------------
778
779
780}; // namespace android
781