Layer.cpp revision dbe6486ca151d0eb1950be0aae347f0eb8ed3442
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
42#define DEBUG_RESIZE    0
43
44
45namespace android {
46
47// ---------------------------------------------------------------------------
48
49Layer::Layer(SurfaceFlinger* flinger,
50        DisplayID display, const sp<Client>& client)
51    :   LayerBaseClient(flinger, display, client),
52        mTextureName(-1U),
53        mQueuedFrames(0),
54        mCurrentTransform(0),
55        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
56        mCurrentOpacity(true),
57        mFormat(PIXEL_FORMAT_NONE),
58        mGLExtensions(GLExtensions::getInstance()),
59        mOpaqueLayer(true),
60        mNeedsDithering(false),
61        mSecure(false),
62        mProtectedByApp(false)
63{
64    mCurrentCrop.makeInvalid();
65    glGenTextures(1, &mTextureName);
66}
67
68void Layer::destroy(RefBase const* base) {
69    mFlinger->destroyLayer(static_cast<LayerBase const*>(base));
70}
71
72void Layer::onFirstRef()
73{
74    LayerBaseClient::onFirstRef();
75    setDestroyer(this);
76
77    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
78        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
79    private:
80        wp<Layer> mLayer;
81        virtual void onFrameAvailable() {
82            sp<Layer> that(mLayer.promote());
83            if (that != 0) {
84                that->onFrameQueued();
85            }
86        }
87    };
88    mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
89    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
90    mSurfaceTexture->setSynchronousMode(true);
91    mSurfaceTexture->setBufferCountServer(2);
92}
93
94Layer::~Layer()
95{
96    glDeleteTextures(1, &mTextureName);
97}
98
99void Layer::onFrameQueued() {
100    android_atomic_inc(&mQueuedFrames);
101    mFlinger->signalEvent();
102}
103
104// called with SurfaceFlinger::mStateLock as soon as the layer is entered
105// in the purgatory list
106void Layer::onRemoved()
107{
108    mSurfaceTexture->abandon();
109}
110
111sp<ISurface> Layer::createSurface()
112{
113    class BSurface : public BnSurface, public LayerCleaner {
114        wp<const Layer> mOwner;
115        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
116            sp<ISurfaceTexture> res;
117            sp<const Layer> that( mOwner.promote() );
118            if (that != NULL) {
119                res = that->mSurfaceTexture;
120            }
121            return res;
122        }
123    public:
124        BSurface(const sp<SurfaceFlinger>& flinger,
125                const sp<Layer>& layer)
126            : LayerCleaner(flinger, layer), mOwner(layer) { }
127    };
128    sp<ISurface> sur(new BSurface(mFlinger, this));
129    return sur;
130}
131
132status_t Layer::setBuffers( uint32_t w, uint32_t h,
133                            PixelFormat format, uint32_t flags)
134{
135    // this surfaces pixel format
136    PixelFormatInfo info;
137    status_t err = getPixelFormatInfo(format, &info);
138    if (err) return err;
139
140    // the display's pixel format
141    const DisplayHardware& hw(graphicPlane(0).displayHardware());
142    uint32_t const maxSurfaceDims = min(
143            hw.getMaxTextureSize(), hw.getMaxViewportDims());
144
145    // never allow a surface larger than what our underlying GL implementation
146    // can handle.
147    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
148        return BAD_VALUE;
149    }
150
151    PixelFormatInfo displayInfo;
152    getPixelFormatInfo(hw.getFormat(), &displayInfo);
153    const uint32_t hwFlags = hw.getFlags();
154
155    mFormat = format;
156
157    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
158    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
159    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
160    mCurrentOpacity = getOpacityForFormat(format);
161
162    mSurfaceTexture->setDefaultBufferSize(w, h);
163    mSurfaceTexture->setDefaultBufferFormat(format);
164
165    // we use the red index
166    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
167    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
168    mNeedsDithering = layerRedsize > displayRedSize;
169
170    return NO_ERROR;
171}
172
173void Layer::setGeometry(hwc_layer_t* hwcl)
174{
175    hwcl->compositionType = HWC_FRAMEBUFFER;
176    hwcl->hints = 0;
177    hwcl->flags = 0;
178    hwcl->transform = 0;
179    hwcl->blending = HWC_BLENDING_NONE;
180
181    // we can't do alpha-fade with the hwc HAL
182    const State& s(drawingState());
183    if (s.alpha < 0xFF) {
184        hwcl->flags = HWC_SKIP_LAYER;
185        return;
186    }
187
188    /*
189     * Transformations are applied in this order:
190     * 1) buffer orientation/flip/mirror
191     * 2) state transformation (window manager)
192     * 3) layer orientation (screen orientation)
193     * (NOTE: the matrices are multiplied in reverse order)
194     */
195
196    const Transform bufferOrientation(mCurrentTransform);
197    const Transform& stateTransform(s.transform);
198    const Transform layerOrientation(mOrientation);
199
200    const Transform tr(layerOrientation * stateTransform * bufferOrientation);
201
202    // this gives us only the "orientation" component of the transform
203    const uint32_t finalTransform = tr.getOrientation();
204
205    // we can only handle simple transformation
206    if (finalTransform & Transform::ROT_INVALID) {
207        hwcl->flags = HWC_SKIP_LAYER;
208        return;
209    }
210
211    hwcl->transform = finalTransform;
212
213    if (!isOpaque()) {
214        hwcl->blending = mPremultipliedAlpha ?
215                HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
216    }
217
218    // scaling is already applied in mTransformedBounds
219    hwcl->displayFrame.left   = mTransformedBounds.left;
220    hwcl->displayFrame.top    = mTransformedBounds.top;
221    hwcl->displayFrame.right  = mTransformedBounds.right;
222    hwcl->displayFrame.bottom = mTransformedBounds.bottom;
223
224    hwcl->visibleRegionScreen.rects =
225            reinterpret_cast<hwc_rect_t const *>(
226                    visibleRegionScreen.getArray(
227                            &hwcl->visibleRegionScreen.numRects));
228}
229
230void Layer::setPerFrameData(hwc_layer_t* hwcl) {
231    const sp<GraphicBuffer>& buffer(mActiveBuffer);
232    if (buffer == NULL) {
233        // this can happen if the client never drew into this layer yet,
234        // or if we ran out of memory. In that case, don't let
235        // HWC handle it.
236        hwcl->flags |= HWC_SKIP_LAYER;
237        hwcl->handle = NULL;
238        return;
239    }
240    hwcl->handle = buffer->handle;
241
242    if (isCropped()) {
243        hwcl->sourceCrop.left   = mCurrentCrop.left;
244        hwcl->sourceCrop.top    = mCurrentCrop.top;
245        hwcl->sourceCrop.right  = mCurrentCrop.right;
246        hwcl->sourceCrop.bottom = mCurrentCrop.bottom;
247    } else {
248        hwcl->sourceCrop.left   = 0;
249        hwcl->sourceCrop.top    = 0;
250        hwcl->sourceCrop.right  = buffer->width;
251        hwcl->sourceCrop.bottom = buffer->height;
252    }
253}
254
255static inline uint16_t pack565(int r, int g, int b) {
256    return (r<<11)|(g<<5)|b;
257}
258void Layer::onDraw(const Region& clip) const
259{
260    if (CC_UNLIKELY(mActiveBuffer == 0)) {
261        // the texture has not been created yet, this Layer has
262        // in fact never been drawn into. This happens frequently with
263        // SurfaceView because the WindowManager can't know when the client
264        // has drawn the first time.
265
266        // If there is nothing under us, we paint the screen in black, otherwise
267        // we just skip this update.
268
269        // figure out if there is something below us
270        Region under;
271        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
272        const size_t count = drawingLayers.size();
273        for (size_t i=0 ; i<count ; ++i) {
274            const sp<LayerBase>& layer(drawingLayers[i]);
275            if (layer.get() == static_cast<LayerBase const*>(this))
276                break;
277            under.orSelf(layer->visibleRegionScreen);
278        }
279        // if not everything below us is covered, we plug the holes!
280        Region holes(clip.subtract(under));
281        if (!holes.isEmpty()) {
282            clearWithOpenGL(holes, 0, 0, 0, 1);
283        }
284        return;
285    }
286
287    GLenum target = mSurfaceTexture->getCurrentTextureTarget();
288    glBindTexture(target, mTextureName);
289    if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
290        // TODO: we could be more subtle with isFixedSize()
291        glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
292        glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
293    } else {
294        glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
295        glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
296    }
297    glEnable(target);
298    glMatrixMode(GL_TEXTURE);
299    glLoadMatrixf(mTextureMatrix);
300    glMatrixMode(GL_MODELVIEW);
301
302    drawWithOpenGL(clip);
303
304    glDisable(target);
305}
306
307// As documented in libhardware header, formats in the range
308// 0x100 - 0x1FF are specific to the HAL implementation, and
309// are known to have no alpha channel
310// TODO: move definition for device-specific range into
311// hardware.h, instead of using hard-coded values here.
312#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
313
314bool Layer::getOpacityForFormat(uint32_t format)
315{
316    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
317        return true;
318    }
319    PixelFormatInfo info;
320    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
321    // in case of error (unknown format), we assume no blending
322    return (err || info.h_alpha <= info.l_alpha);
323}
324
325
326bool Layer::isOpaque() const
327{
328    // if we don't have a buffer yet, we're translucent regardless of the
329    // layer's opaque flag.
330    if (mActiveBuffer == 0) {
331        return false;
332    }
333
334    // if the layer has the opaque flag, then we're always opaque,
335    // otherwise we use the current buffer's format.
336    return mOpaqueLayer || mCurrentOpacity;
337}
338
339bool Layer::isProtected() const
340{
341    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
342    return (activeBuffer != 0) &&
343            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
344}
345
346uint32_t Layer::doTransaction(uint32_t flags)
347{
348    const Layer::State& front(drawingState());
349    const Layer::State& temp(currentState());
350
351    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
352            (front.requested_h != temp.requested_h);
353
354    if (sizeChanged) {
355        // the size changed, we need to ask our client to request a new buffer
356        LOGD_IF(DEBUG_RESIZE,
357                "doTransaction: "
358                "resize (layer=%p), requested (%dx%d), drawing (%d,%d), "
359                "scalingMode=%d",
360                this,
361                int(temp.requested_w), int(temp.requested_h),
362                int(front.requested_w), int(front.requested_h),
363                mCurrentScalingMode);
364
365        if (!isFixedSize()) {
366            // we're being resized and there is a freeze display request,
367            // acquire a freeze lock, so that the screen stays put
368            // until we've redrawn at the new size; this is to avoid
369            // glitches upon orientation changes.
370            if (mFlinger->hasFreezeRequest()) {
371                // if the surface is hidden, don't try to acquire the
372                // freeze lock, since hidden surfaces may never redraw
373                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
374                    mFreezeLock = mFlinger->getFreezeLock();
375                }
376            }
377
378            // this will make sure LayerBase::doTransaction doesn't update
379            // the drawing state's size
380            Layer::State& editDraw(mDrawingState);
381            editDraw.requested_w = temp.requested_w;
382            editDraw.requested_h = temp.requested_h;
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, temp.requested_h);
387        }
388    }
389
390    if (temp.sequence != front.sequence) {
391        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
392            // this surface is now hidden, so it shouldn't hold a freeze lock
393            // (it may never redraw, which is fine if it is hidden)
394            mFreezeLock.clear();
395        }
396    }
397
398    return LayerBase::doTransaction(flags);
399}
400
401bool Layer::isFixedSize() const {
402    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
403}
404
405bool Layer::isCropped() const {
406    return !mCurrentCrop.isEmpty();
407}
408
409// ----------------------------------------------------------------------------
410// pageflip handling...
411// ----------------------------------------------------------------------------
412
413void Layer::lockPageFlip(bool& recomputeVisibleRegions)
414{
415    if (mQueuedFrames > 0) {
416        const bool oldOpacity = isOpaque();
417
418        // signal another event if we have more frames pending
419        if (android_atomic_dec(&mQueuedFrames) > 1) {
420            mFlinger->signalEvent();
421        }
422
423        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
424            // something happened!
425            recomputeVisibleRegions = true;
426            return;
427        }
428
429        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
430        mSurfaceTexture->getTransformMatrix(mTextureMatrix);
431
432        const Rect crop(mSurfaceTexture->getCurrentCrop());
433        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
434        const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
435        if ((crop != mCurrentCrop) ||
436            (transform != mCurrentTransform) ||
437            (scalingMode != mCurrentScalingMode))
438        {
439            mCurrentCrop = crop;
440            mCurrentTransform = transform;
441            mCurrentScalingMode = scalingMode;
442            mFlinger->invalidateHwcGeometry();
443        }
444
445        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
446        if (oldOpacity != isOpaque()) {
447            recomputeVisibleRegions = true;
448        }
449
450        const GLenum target(mSurfaceTexture->getCurrentTextureTarget());
451        glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
452        glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
453
454        // update the layer size and release freeze-lock
455        const Layer::State& front(drawingState());
456
457        // FIXME: mPostedDirtyRegion = dirty & bounds
458        mPostedDirtyRegion.set(front.w, front.h);
459
460
461        if ((front.w != front.requested_w) ||
462            (front.h != front.requested_h))
463        {
464            // check that we received a buffer of the right size
465            // (Take the buffer's orientation into account)
466            sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
467            uint32_t bufWidth  = newFrontBuffer->getWidth();
468            uint32_t bufHeight = newFrontBuffer->getHeight();
469            if (mCurrentTransform & Transform::ROT_90) {
470                swap(bufWidth, bufHeight);
471            }
472
473            if (isFixedSize() ||
474                    (bufWidth == front.requested_w &&
475                    bufHeight == front.requested_h))
476            {
477                // Here we pretend the transaction happened by updating the
478                // current and drawing states. Drawing state is only accessed
479                // in this thread, no need to have it locked
480                Layer::State& editDraw(mDrawingState);
481                editDraw.w = editDraw.requested_w;
482                editDraw.h = editDraw.requested_h;
483
484                // We also need to update the current state so that we don't
485                // end-up doing too much work during the next transaction.
486                // NOTE: We actually don't need hold the transaction lock here
487                // because State::w and State::h are only accessed from
488                // this thread
489                Layer::State& editTemp(currentState());
490                editTemp.w = editDraw.w;
491                editTemp.h = editDraw.h;
492
493                // recompute visible region
494                recomputeVisibleRegions = true;
495
496                // we now have the correct size, unfreeze the screen
497                mFreezeLock.clear();
498            }
499
500            LOGD_IF(DEBUG_RESIZE,
501                    "lockPageFlip : "
502                    "       (layer=%p), buffer (%ux%u, tr=%02x), "
503                    "requested (%dx%d)",
504                    this,
505                    bufWidth, bufHeight, mCurrentTransform,
506                    front.requested_w, front.requested_h);
507        }
508    }
509}
510
511void Layer::unlockPageFlip(
512        const Transform& planeTransform, Region& outDirtyRegion)
513{
514    Region dirtyRegion(mPostedDirtyRegion);
515    if (!dirtyRegion.isEmpty()) {
516        mPostedDirtyRegion.clear();
517        // The dirty region is given in the layer's coordinate space
518        // transform the dirty region by the surface's transformation
519        // and the global transformation.
520        const Layer::State& s(drawingState());
521        const Transform tr(planeTransform * s.transform);
522        dirtyRegion = tr.transform(dirtyRegion);
523
524        // At this point, the dirty region is in screen space.
525        // Make sure it's constrained by the visible region (which
526        // is in screen space as well).
527        dirtyRegion.andSelf(visibleRegionScreen);
528        outDirtyRegion.orSelf(dirtyRegion);
529    }
530    if (visibleRegionScreen.isEmpty()) {
531        // an invisible layer should not hold a freeze-lock
532        // (because it may never be updated and therefore never release it)
533        mFreezeLock.clear();
534    }
535}
536
537void Layer::dump(String8& result, char* buffer, size_t SIZE) const
538{
539    LayerBaseClient::dump(result, buffer, SIZE);
540
541    sp<const GraphicBuffer> buf0(mActiveBuffer);
542    uint32_t w0=0, h0=0, s0=0, f0=0;
543    if (buf0 != 0) {
544        w0 = buf0->getWidth();
545        h0 = buf0->getHeight();
546        s0 = buf0->getStride();
547        f0 = buf0->format;
548    }
549    snprintf(buffer, SIZE,
550            "      "
551            "format=%2d, activeBuffer=[%3ux%3u:%3u,%3u],"
552            " freezeLock=%p, queued-frames=%d\n",
553            mFormat, w0, h0, s0,f0,
554            getFreezeLock().get(), mQueuedFrames);
555
556    result.append(buffer);
557
558    if (mSurfaceTexture != 0) {
559        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
560    }
561}
562
563uint32_t Layer::getEffectiveUsage(uint32_t usage) const
564{
565    // TODO: should we do something special if mSecure is set?
566    if (mProtectedByApp) {
567        // need a hardware-protected path to external video sink
568        usage |= GraphicBuffer::USAGE_PROTECTED;
569    }
570    return usage;
571}
572
573// ---------------------------------------------------------------------------
574
575
576}; // namespace android
577