Layer.cpp revision 82d7ab6c7e0cf971e515134ccf072682dd1a2cdb
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdlib.h>
18#include <stdint.h>
19#include <sys/types.h>
20
21#include <cutils/compiler.h>
22#include <cutils/native_handle.h>
23#include <cutils/properties.h>
24
25#include <utils/Errors.h>
26#include <utils/Log.h>
27#include <utils/StopWatch.h>
28
29#include <ui/GraphicBuffer.h>
30#include <ui/PixelFormat.h>
31
32#include <surfaceflinger/Surface.h>
33
34#include "clz.h"
35#include "DisplayHardware/DisplayHardware.h"
36#include "DisplayHardware/HWComposer.h"
37#include "GLExtensions.h"
38#include "Layer.h"
39#include "SurfaceFlinger.h"
40#include "SurfaceTextureLayer.h"
41#include <math.h>
42
43#define DEBUG_RESIZE    0
44
45
46namespace android {
47
48// ---------------------------------------------------------------------------
49
50Layer::Layer(SurfaceFlinger* flinger,
51        DisplayID display, const sp<Client>& client)
52    :   LayerBaseClient(flinger, display, client),
53        mTextureName(-1U),
54        mQueuedFrames(0),
55        mCurrentTransform(0),
56        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
57        mCurrentOpacity(true),
58        mFrameLatencyNeeded(false),
59        mFrameLatencyOffset(0),
60        mFormat(PIXEL_FORMAT_NONE),
61        mGLExtensions(GLExtensions::getInstance()),
62        mOpaqueLayer(true),
63        mNeedsDithering(false),
64        mSecure(false),
65        mProtectedByApp(false)
66{
67    mCurrentCrop.makeInvalid();
68    glGenTextures(1, &mTextureName);
69}
70
71void Layer::onLayerDisplayed() {
72    if (mFrameLatencyNeeded) {
73        const DisplayHardware& hw(graphicPlane(0).displayHardware());
74        mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
75        mFrameStats[mFrameLatencyOffset].set = systemTime();
76        mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
77        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
78        mFrameLatencyNeeded = false;
79    }
80}
81
82void Layer::onFirstRef()
83{
84    LayerBaseClient::onFirstRef();
85
86    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
87        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
88    private:
89        wp<Layer> mLayer;
90        virtual void onFrameAvailable() {
91            sp<Layer> that(mLayer.promote());
92            if (that != 0) {
93                that->onFrameQueued();
94            }
95        }
96    };
97    mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
98    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
99    mSurfaceTexture->setSynchronousMode(true);
100    mSurfaceTexture->setBufferCountServer(2);
101}
102
103Layer::~Layer()
104{
105    mFlinger->postMessageAsync(
106            new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
107}
108
109void Layer::onFrameQueued() {
110    android_atomic_inc(&mQueuedFrames);
111    mFlinger->signalEvent();
112}
113
114// called with SurfaceFlinger::mStateLock as soon as the layer is entered
115// in the purgatory list
116void Layer::onRemoved()
117{
118    mSurfaceTexture->abandon();
119}
120
121void Layer::setName(const String8& name) {
122    LayerBase::setName(name);
123    mSurfaceTexture->setName(name);
124}
125
126sp<ISurface> Layer::createSurface()
127{
128    class BSurface : public BnSurface, public LayerCleaner {
129        wp<const Layer> mOwner;
130        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
131            sp<ISurfaceTexture> res;
132            sp<const Layer> that( mOwner.promote() );
133            if (that != NULL) {
134                res = that->mSurfaceTexture;
135            }
136            return res;
137        }
138    public:
139        BSurface(const sp<SurfaceFlinger>& flinger,
140                const sp<Layer>& layer)
141            : LayerCleaner(flinger, layer), mOwner(layer) { }
142    };
143    sp<ISurface> sur(new BSurface(mFlinger, this));
144    return sur;
145}
146
147wp<IBinder> Layer::getSurfaceTextureBinder() const
148{
149    return mSurfaceTexture->asBinder();
150}
151
152status_t Layer::setBuffers( uint32_t w, uint32_t h,
153                            PixelFormat format, uint32_t flags)
154{
155    // this surfaces pixel format
156    PixelFormatInfo info;
157    status_t err = getPixelFormatInfo(format, &info);
158    if (err) return err;
159
160    // the display's pixel format
161    const DisplayHardware& hw(graphicPlane(0).displayHardware());
162    uint32_t const maxSurfaceDims = min(
163            hw.getMaxTextureSize(), hw.getMaxViewportDims());
164
165    // never allow a surface larger than what our underlying GL implementation
166    // can handle.
167    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
168        return BAD_VALUE;
169    }
170
171    PixelFormatInfo displayInfo;
172    getPixelFormatInfo(hw.getFormat(), &displayInfo);
173    const uint32_t hwFlags = hw.getFlags();
174
175    mFormat = format;
176
177    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
178    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
179    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
180    mCurrentOpacity = getOpacityForFormat(format);
181
182    mSurfaceTexture->setDefaultBufferSize(w, h);
183    mSurfaceTexture->setDefaultBufferFormat(format);
184
185    // we use the red index
186    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
187    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
188    mNeedsDithering = layerRedsize > displayRedSize;
189
190    return NO_ERROR;
191}
192
193void Layer::setGeometry(hwc_layer_t* hwcl)
194{
195    LayerBaseClient::setGeometry(hwcl);
196
197    hwcl->flags &= ~HWC_SKIP_LAYER;
198
199    // we can't do alpha-fade with the hwc HAL
200    const State& s(drawingState());
201    if (s.alpha < 0xFF) {
202        hwcl->flags = HWC_SKIP_LAYER;
203    }
204
205    /*
206     * Transformations are applied in this order:
207     * 1) buffer orientation/flip/mirror
208     * 2) state transformation (window manager)
209     * 3) layer orientation (screen orientation)
210     * mTransform is already the composition of (2) and (3)
211     * (NOTE: the matrices are multiplied in reverse order)
212     */
213
214    const Transform bufferOrientation(mCurrentTransform);
215    const Transform tr(mTransform * bufferOrientation);
216
217    // this gives us only the "orientation" component of the transform
218    const uint32_t finalTransform = tr.getOrientation();
219
220    // we can only handle simple transformation
221    if (finalTransform & Transform::ROT_INVALID) {
222        hwcl->flags = HWC_SKIP_LAYER;
223    } else {
224        hwcl->transform = finalTransform;
225    }
226
227    if (isCropped()) {
228        hwcl->sourceCrop.left   = mCurrentCrop.left;
229        hwcl->sourceCrop.top    = mCurrentCrop.top;
230        hwcl->sourceCrop.right  = mCurrentCrop.right;
231        hwcl->sourceCrop.bottom = mCurrentCrop.bottom;
232    } else {
233        const sp<GraphicBuffer>& buffer(mActiveBuffer);
234        hwcl->sourceCrop.left   = 0;
235        hwcl->sourceCrop.top    = 0;
236        if (buffer != NULL) {
237            hwcl->sourceCrop.right  = buffer->width;
238            hwcl->sourceCrop.bottom = buffer->height;
239        } else {
240            hwcl->sourceCrop.right  = mTransformedBounds.width();
241            hwcl->sourceCrop.bottom = mTransformedBounds.height();
242        }
243    }
244}
245
246void Layer::setPerFrameData(hwc_layer_t* hwcl) {
247    const sp<GraphicBuffer>& buffer(mActiveBuffer);
248    if (buffer == NULL) {
249        // this can happen if the client never drew into this layer yet,
250        // or if we ran out of memory. In that case, don't let
251        // HWC handle it.
252        hwcl->flags |= HWC_SKIP_LAYER;
253        hwcl->handle = NULL;
254    } else {
255        hwcl->handle = buffer->handle;
256    }
257}
258
259void Layer::onDraw(const Region& clip) const
260{
261    if (CC_UNLIKELY(mActiveBuffer == 0)) {
262        // the texture has not been created yet, this Layer has
263        // in fact never been drawn into. This happens frequently with
264        // SurfaceView because the WindowManager can't know when the client
265        // has drawn the first time.
266
267        // If there is nothing under us, we paint the screen in black, otherwise
268        // we just skip this update.
269
270        // figure out if there is something below us
271        Region under;
272        const SurfaceFlinger::LayerVector& drawingLayers(
273                mFlinger->mDrawingState.layersSortedByZ);
274        const size_t count = drawingLayers.size();
275        for (size_t i=0 ; i<count ; ++i) {
276            const sp<LayerBase>& layer(drawingLayers[i]);
277            if (layer.get() == static_cast<LayerBase const*>(this))
278                break;
279            under.orSelf(layer->visibleRegionScreen);
280        }
281        // if not everything below us is covered, we plug the holes!
282        Region holes(clip.subtract(under));
283        if (!holes.isEmpty()) {
284            clearWithOpenGL(holes, 0, 0, 0, 1);
285        }
286        return;
287    }
288
289    if (!isProtected()) {
290        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
291        GLenum filter = GL_NEAREST;
292        if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
293            // TODO: we could be more subtle with isFixedSize()
294            filter = GL_LINEAR;
295        }
296        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
297        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
298        glMatrixMode(GL_TEXTURE);
299        glLoadMatrixf(mTextureMatrix);
300        glMatrixMode(GL_MODELVIEW);
301        glDisable(GL_TEXTURE_2D);
302        glEnable(GL_TEXTURE_EXTERNAL_OES);
303    } else {
304        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
305        glMatrixMode(GL_TEXTURE);
306        glLoadIdentity();
307        glMatrixMode(GL_MODELVIEW);
308        glDisable(GL_TEXTURE_EXTERNAL_OES);
309        glEnable(GL_TEXTURE_2D);
310    }
311
312    drawWithOpenGL(clip);
313
314    glDisable(GL_TEXTURE_EXTERNAL_OES);
315    glDisable(GL_TEXTURE_2D);
316}
317
318// As documented in libhardware header, formats in the range
319// 0x100 - 0x1FF are specific to the HAL implementation, and
320// are known to have no alpha channel
321// TODO: move definition for device-specific range into
322// hardware.h, instead of using hard-coded values here.
323#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
324
325bool Layer::getOpacityForFormat(uint32_t format)
326{
327    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
328        return true;
329    }
330    PixelFormatInfo info;
331    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
332    // in case of error (unknown format), we assume no blending
333    return (err || info.h_alpha <= info.l_alpha);
334}
335
336
337bool Layer::isOpaque() const
338{
339    // if we don't have a buffer yet, we're translucent regardless of the
340    // layer's opaque flag.
341    if (mActiveBuffer == 0) {
342        return false;
343    }
344
345    // if the layer has the opaque flag, then we're always opaque,
346    // otherwise we use the current buffer's format.
347    return mOpaqueLayer || mCurrentOpacity;
348}
349
350bool Layer::isProtected() const
351{
352    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
353    return (activeBuffer != 0) &&
354            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
355}
356
357uint32_t Layer::doTransaction(uint32_t flags)
358{
359    const Layer::State& front(drawingState());
360    const Layer::State& temp(currentState());
361
362    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
363            (front.requested_h != temp.requested_h);
364
365    if (sizeChanged) {
366        // the size changed, we need to ask our client to request a new buffer
367        ALOGD_IF(DEBUG_RESIZE,
368                "doTransaction: "
369                "resize (layer=%p), requested (%dx%d), drawing (%d,%d), "
370                "scalingMode=%d",
371                this,
372                int(temp.requested_w), int(temp.requested_h),
373                int(front.requested_w), int(front.requested_h),
374                mCurrentScalingMode);
375
376        if (!isFixedSize()) {
377            // this will make sure LayerBase::doTransaction doesn't update
378            // the drawing state's size
379            Layer::State& editDraw(mDrawingState);
380            editDraw.requested_w = temp.requested_w;
381            editDraw.requested_h = temp.requested_h;
382        }
383
384        // record the new size, form this point on, when the client request
385        // a buffer, it'll get the new size.
386        mSurfaceTexture->setDefaultBufferSize(temp.requested_w,
387                temp.requested_h);
388    }
389
390    return LayerBase::doTransaction(flags);
391}
392
393bool Layer::isFixedSize() const {
394    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
395}
396
397bool Layer::isCropped() const {
398    return !mCurrentCrop.isEmpty();
399}
400
401// ----------------------------------------------------------------------------
402// pageflip handling...
403// ----------------------------------------------------------------------------
404
405void Layer::lockPageFlip(bool& recomputeVisibleRegions)
406{
407    if (mQueuedFrames > 0) {
408        // Capture the old state of the layer for comparisons later
409        const bool oldOpacity = isOpaque();
410        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
411
412        // signal another event if we have more frames pending
413        if (android_atomic_dec(&mQueuedFrames) > 1) {
414            mFlinger->signalEvent();
415        }
416
417        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
418            // something happened!
419            recomputeVisibleRegions = true;
420            return;
421        }
422
423        // update the active buffer
424        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
425        mFrameLatencyNeeded = true;
426
427        const Rect crop(mSurfaceTexture->getCurrentCrop());
428        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
429        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
430        if ((crop != mCurrentCrop) ||
431            (transform != mCurrentTransform) ||
432            (scalingMode != mCurrentScalingMode))
433        {
434            mCurrentCrop = crop;
435            mCurrentTransform = transform;
436            mCurrentScalingMode = scalingMode;
437            mFlinger->invalidateHwcGeometry();
438        }
439
440        GLfloat textureMatrix[16];
441        mSurfaceTexture->getTransformMatrix(textureMatrix);
442        if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) {
443            memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix));
444            mFlinger->invalidateHwcGeometry();
445        }
446
447        uint32_t bufWidth  = mActiveBuffer->getWidth();
448        uint32_t bufHeight = mActiveBuffer->getHeight();
449        if (oldActiveBuffer != NULL) {
450            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
451                bufHeight != uint32_t(oldActiveBuffer->height)) {
452                mFlinger->invalidateHwcGeometry();
453            }
454        }
455
456        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
457        if (oldOpacity != isOpaque()) {
458            recomputeVisibleRegions = true;
459        }
460
461        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
462        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
463
464        // update the layer size if needed
465        const Layer::State& front(drawingState());
466
467        // FIXME: mPostedDirtyRegion = dirty & bounds
468        mPostedDirtyRegion.set(front.w, front.h);
469
470        if ((front.w != front.requested_w) ||
471            (front.h != front.requested_h))
472        {
473            // check that we received a buffer of the right size
474            // (Take the buffer's orientation into account)
475            if (mCurrentTransform & Transform::ROT_90) {
476                swap(bufWidth, bufHeight);
477            }
478
479            if (isFixedSize() ||
480                    (bufWidth == front.requested_w &&
481                    bufHeight == front.requested_h))
482            {
483                // Here we pretend the transaction happened by updating the
484                // current and drawing states. Drawing state is only accessed
485                // in this thread, no need to have it locked
486                Layer::State& editDraw(mDrawingState);
487                editDraw.w = editDraw.requested_w;
488                editDraw.h = editDraw.requested_h;
489
490                // We also need to update the current state so that we don't
491                // end-up doing too much work during the next transaction.
492                // NOTE: We actually don't need hold the transaction lock here
493                // because State::w and State::h are only accessed from
494                // this thread
495                Layer::State& editTemp(currentState());
496                editTemp.w = editDraw.w;
497                editTemp.h = editDraw.h;
498
499                // recompute visible region
500                recomputeVisibleRegions = true;
501            }
502
503            ALOGD_IF(DEBUG_RESIZE,
504                    "lockPageFlip : "
505                    "       (layer=%p), buffer (%ux%u, tr=%02x), "
506                    "requested (%dx%d)",
507                    this,
508                    bufWidth, bufHeight, mCurrentTransform,
509                    front.requested_w, front.requested_h);
510        }
511    }
512}
513
514void Layer::unlockPageFlip(
515        const Transform& planeTransform, Region& outDirtyRegion)
516{
517    Region dirtyRegion(mPostedDirtyRegion);
518    if (!dirtyRegion.isEmpty()) {
519        mPostedDirtyRegion.clear();
520        // The dirty region is given in the layer's coordinate space
521        // transform the dirty region by the surface's transformation
522        // and the global transformation.
523        const Layer::State& s(drawingState());
524        const Transform tr(planeTransform * s.transform);
525        dirtyRegion = tr.transform(dirtyRegion);
526
527        // At this point, the dirty region is in screen space.
528        // Make sure it's constrained by the visible region (which
529        // is in screen space as well).
530        dirtyRegion.andSelf(visibleRegionScreen);
531        outDirtyRegion.orSelf(dirtyRegion);
532    }
533}
534
535void Layer::dump(String8& result, char* buffer, size_t SIZE) const
536{
537    LayerBaseClient::dump(result, buffer, SIZE);
538
539    sp<const GraphicBuffer> buf0(mActiveBuffer);
540    uint32_t w0=0, h0=0, s0=0, f0=0;
541    if (buf0 != 0) {
542        w0 = buf0->getWidth();
543        h0 = buf0->getHeight();
544        s0 = buf0->getStride();
545        f0 = buf0->format;
546    }
547    snprintf(buffer, SIZE,
548            "      "
549            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
550            " transform-hint=0x%02x, queued-frames=%d\n",
551            mFormat, w0, h0, s0,f0,
552            getTransformHint(), mQueuedFrames);
553
554    result.append(buffer);
555
556    LayerBase::dumpStats(result, buffer, SIZE);
557
558    if (mSurfaceTexture != 0) {
559        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
560    }
561}
562
563void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
564{
565    LayerBaseClient::dumpStats(result, buffer, SIZE);
566    const size_t o = mFrameLatencyOffset;
567    const DisplayHardware& hw(graphicPlane(0).displayHardware());
568    const nsecs_t period = hw.getRefreshPeriod();
569    result.appendFormat("%lld\n", period);
570    for (size_t i=0 ; i<128 ; i++) {
571        const size_t index = (o+i) % 128;
572        const nsecs_t time_app   = mFrameStats[index].timestamp;
573        const nsecs_t time_set   = mFrameStats[index].set;
574        const nsecs_t time_vsync = mFrameStats[index].vsync;
575        result.appendFormat("%lld\t%lld\t%lld\n",
576                time_app,
577                time_vsync,
578                time_set);
579    }
580    result.append("\n");
581}
582
583uint32_t Layer::getEffectiveUsage(uint32_t usage) const
584{
585    // TODO: should we do something special if mSecure is set?
586    if (mProtectedByApp) {
587        // need a hardware-protected path to external video sink
588        usage |= GraphicBuffer::USAGE_PROTECTED;
589    }
590    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
591    return usage;
592}
593
594uint32_t Layer::getTransformHint() const {
595    uint32_t orientation = 0;
596    if (!mFlinger->mDebugDisableTransformHint) {
597        orientation = getPlaneOrientation();
598        if (orientation & Transform::ROT_INVALID) {
599            orientation = 0;
600        }
601    }
602    return orientation;
603}
604
605// ---------------------------------------------------------------------------
606
607
608}; // namespace android
609