Layer.cpp revision f345069099a13f0c2dd91f1fa92786643e4becb0
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/properties.h>
22#include <cutils/native_handle.h>
23
24#include <utils/Errors.h>
25#include <utils/Log.h>
26#include <utils/StopWatch.h>
27
28#include <ui/GraphicBuffer.h>
29#include <ui/PixelFormat.h>
30
31#include <surfaceflinger/Surface.h>
32
33#include "clz.h"
34#include "GLExtensions.h"
35#include "Layer.h"
36#include "SurfaceFlinger.h"
37#include "DisplayHardware/DisplayHardware.h"
38#include "DisplayHardware/HWComposer.h"
39
40
41#define DEBUG_RESIZE    0
42
43
44namespace android {
45
46template <typename T> inline T min(T a, T b) {
47    return a<b ? a : b;
48}
49
50// ---------------------------------------------------------------------------
51
52Layer::Layer(SurfaceFlinger* flinger,
53        DisplayID display, const sp<Client>& client)
54    :   LayerBaseClient(flinger, display, client),
55        mGLExtensions(GLExtensions::getInstance()),
56        mNeedsBlending(true),
57        mNeedsDithering(false),
58        mSecure(false),
59        mTextureManager(),
60        mBufferManager(mTextureManager),
61        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
62{
63}
64
65Layer::~Layer()
66{
67    // FIXME: must be called from the main UI thread
68    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
69    mBufferManager.destroy(dpy);
70
71    // we can use getUserClientUnsafe here because we know we're
72    // single-threaded at that point.
73    sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
74    if (ourClient != 0) {
75        ourClient->detachLayer(this);
76    }
77}
78
79status_t Layer::setToken(const sp<UserClient>& userClient,
80        SharedClient* sharedClient, int32_t token)
81{
82    sp<SharedBufferServer> lcblk = new SharedBufferServer(
83            sharedClient, token, mBufferManager.getDefaultBufferCount(),
84            getIdentity());
85
86    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
87
88    LOGE_IF(err != NO_ERROR,
89            "ClientRef::setToken(%p, %p, %u) failed",
90            userClient.get(), lcblk.get(), token);
91
92    if (err == NO_ERROR) {
93        // we need to free the buffers associated with this surface
94    }
95
96    return err;
97}
98
99int32_t Layer::getToken() const
100{
101    return mUserClientRef.getToken();
102}
103
104sp<UserClient> Layer::getClient() const
105{
106    return mUserClientRef.getClient();
107}
108
109// called with SurfaceFlinger::mStateLock as soon as the layer is entered
110// in the purgatory list
111void Layer::onRemoved()
112{
113    ClientRef::Access sharedClient(mUserClientRef);
114    SharedBufferServer* lcblk(sharedClient.get());
115    if (lcblk) {
116        // wake up the condition
117        lcblk->setStatus(NO_INIT);
118    }
119}
120
121sp<LayerBaseClient::Surface> Layer::createSurface() const
122{
123    return mSurface;
124}
125
126status_t Layer::ditch()
127{
128    // NOTE: Called from the main UI thread
129
130    // the layer is not on screen anymore. free as much resources as possible
131    mFreezeLock.clear();
132
133    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
134    mBufferManager.destroy(dpy);
135    mSurface.clear();
136
137    Mutex::Autolock _l(mLock);
138    mWidth = mHeight = 0;
139    return NO_ERROR;
140}
141
142status_t Layer::setBuffers( uint32_t w, uint32_t h,
143                            PixelFormat format, uint32_t flags)
144{
145    // this surfaces pixel format
146    PixelFormatInfo info;
147    status_t err = getPixelFormatInfo(format, &info);
148    if (err) return err;
149
150    // the display's pixel format
151    const DisplayHardware& hw(graphicPlane(0).displayHardware());
152    uint32_t const maxSurfaceDims = min(
153            hw.getMaxTextureSize(), hw.getMaxViewportDims());
154
155    // never allow a surface larger than what our underlying GL implementation
156    // can handle.
157    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
158        return BAD_VALUE;
159    }
160
161    PixelFormatInfo displayInfo;
162    getPixelFormatInfo(hw.getFormat(), &displayInfo);
163    const uint32_t hwFlags = hw.getFlags();
164
165    mFormat = format;
166    mWidth  = w;
167    mHeight = h;
168
169    mReqFormat = format;
170    mReqWidth = w;
171    mReqHeight = h;
172
173    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
174    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
175            (flags & ISurfaceComposer::eOpaque) == 0;
176
177    // we use the red index
178    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
179    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
180    mNeedsDithering = layerRedsize > displayRedSize;
181
182    mSurface = new SurfaceLayer(mFlinger, this);
183    return NO_ERROR;
184}
185
186void Layer::setGeometry(hwc_layer_t* hwcl)
187{
188    hwcl->compositionType = HWC_FRAMEBUFFER;
189    hwcl->hints = 0;
190    hwcl->flags = 0;
191    hwcl->transform = 0;
192    hwcl->blending = HWC_BLENDING_NONE;
193
194    // we can't do alpha-fade with the hwc HAL
195    const State& s(drawingState());
196    if (s.alpha < 0xFF) {
197        hwcl->flags = HWC_SKIP_LAYER;
198        return;
199    }
200
201    // we can only handle simple transformation
202    if (mOrientation & Transform::ROT_INVALID) {
203        hwcl->flags = HWC_SKIP_LAYER;
204        return;
205    }
206
207    Transform tr(Transform(mOrientation) * Transform(mBufferTransform));
208    hwcl->transform = tr.getOrientation();
209
210    if (needsBlending()) {
211        hwcl->blending = mPremultipliedAlpha ?
212                HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
213    }
214
215    hwcl->displayFrame.left   = mTransformedBounds.left;
216    hwcl->displayFrame.top    = mTransformedBounds.top;
217    hwcl->displayFrame.right  = mTransformedBounds.right;
218    hwcl->displayFrame.bottom = mTransformedBounds.bottom;
219
220    hwcl->visibleRegionScreen.rects =
221            reinterpret_cast<hwc_rect_t const *>(
222                    visibleRegionScreen.getArray(
223                            &hwcl->visibleRegionScreen.numRects));
224}
225
226void Layer::setPerFrameData(hwc_layer_t* hwcl) {
227    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
228    if (buffer == NULL) {
229        // this situation can happen if we ran out of memory for instance.
230        // not much we can do. continue to use whatever texture was bound
231        // to this context.
232        hwcl->handle = NULL;
233        return;
234    }
235    hwcl->handle = buffer->handle;
236
237    if (!mBufferCrop.isEmpty()) {
238        hwcl->sourceCrop.left   = mBufferCrop.left;
239        hwcl->sourceCrop.top    = mBufferCrop.top;
240        hwcl->sourceCrop.right  = mBufferCrop.right;
241        hwcl->sourceCrop.bottom = mBufferCrop.bottom;
242    } else {
243        hwcl->sourceCrop.left   = 0;
244        hwcl->sourceCrop.top    = 0;
245        hwcl->sourceCrop.right  = buffer->width;
246        hwcl->sourceCrop.bottom = buffer->height;
247    }
248}
249
250void Layer::reloadTexture(const Region& dirty)
251{
252    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
253    if (buffer == NULL) {
254        // this situation can happen if we ran out of memory for instance.
255        // not much we can do. continue to use whatever texture was bound
256        // to this context.
257        return;
258    }
259
260    if (mGLExtensions.haveDirectTexture()) {
261        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
262        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
263            // not sure what we can do here...
264            goto slowpath;
265        }
266    } else {
267slowpath:
268        GGLSurface t;
269        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
270            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
271            LOGE_IF(res, "error %d (%s) locking buffer %p",
272                    res, strerror(res), buffer.get());
273            if (res == NO_ERROR) {
274                mBufferManager.loadTexture(dirty, t);
275                buffer->unlock();
276            }
277        } else {
278            // we can't do anything
279        }
280    }
281}
282
283void Layer::drawForSreenShot() const
284{
285    const bool currentFiltering = mNeedsFiltering;
286    const_cast<Layer*>(this)->mNeedsFiltering = true;
287    LayerBase::drawForSreenShot();
288    const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering;
289}
290
291void Layer::onDraw(const Region& clip) const
292{
293    Texture tex(mBufferManager.getActiveTexture());
294    if (tex.name == -1LU) {
295        // the texture has not been created yet, this Layer has
296        // in fact never been drawn into. This happens frequently with
297        // SurfaceView because the WindowManager can't know when the client
298        // has drawn the first time.
299
300        // If there is nothing under us, we paint the screen in black, otherwise
301        // we just skip this update.
302
303        // figure out if there is something below us
304        Region under;
305        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
306        const size_t count = drawingLayers.size();
307        for (size_t i=0 ; i<count ; ++i) {
308            const sp<LayerBase>& layer(drawingLayers[i]);
309            if (layer.get() == static_cast<LayerBase const*>(this))
310                break;
311            under.orSelf(layer->visibleRegionScreen);
312        }
313        // if not everything below us is covered, we plug the holes!
314        Region holes(clip.subtract(under));
315        if (!holes.isEmpty()) {
316            clearWithOpenGL(holes, 0, 0, 0, 1);
317        }
318        return;
319    }
320    drawWithOpenGL(clip, tex);
321}
322
323bool Layer::needsFiltering() const
324{
325    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
326        // if our buffer is not the same size than ourselves,
327        // we need filtering.
328        Mutex::Autolock _l(mLock);
329        if (mNeedsScaling)
330            return true;
331    }
332    return LayerBase::needsFiltering();
333}
334
335
336status_t Layer::setBufferCount(int bufferCount)
337{
338    ClientRef::Access sharedClient(mUserClientRef);
339    SharedBufferServer* lcblk(sharedClient.get());
340    if (!lcblk) {
341        // oops, the client is already gone
342        return DEAD_OBJECT;
343    }
344
345    // NOTE: lcblk->resize() is protected by an internal lock
346    status_t err = lcblk->resize(bufferCount);
347    if (err == NO_ERROR) {
348        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
349        mBufferManager.resize(bufferCount, mFlinger, dpy);
350    }
351
352    return err;
353}
354
355sp<GraphicBuffer> Layer::requestBuffer(int index,
356        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
357        uint32_t usage)
358{
359    sp<GraphicBuffer> buffer;
360
361    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
362        return buffer;
363
364    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
365        return buffer;
366
367    // this ensures our client doesn't go away while we're accessing
368    // the shared area.
369    ClientRef::Access sharedClient(mUserClientRef);
370    SharedBufferServer* lcblk(sharedClient.get());
371    if (!lcblk) {
372        // oops, the client is already gone
373        return buffer;
374    }
375
376    /*
377     * This is called from the client's Surface::dequeue(). This can happen
378     * at any time, especially while we're in the middle of using the
379     * buffer 'index' as our front buffer.
380     */
381
382    status_t err = NO_ERROR;
383    uint32_t w, h, f;
384    { // scope for the lock
385        Mutex::Autolock _l(mLock);
386
387        // zero means default
388        const bool fixedSize = reqWidth && reqHeight;
389        if (!reqFormat) reqFormat = mFormat;
390        if (!reqWidth)  reqWidth = mWidth;
391        if (!reqHeight) reqHeight = mHeight;
392
393        w = reqWidth;
394        h = reqHeight;
395        f = reqFormat;
396
397        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
398                (reqFormat != mReqFormat)) {
399            mReqWidth  = reqWidth;
400            mReqHeight = reqHeight;
401            mReqFormat = reqFormat;
402            mFixedSize = fixedSize;
403            mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
404
405            lcblk->reallocateAllExcept(index);
406        }
407    }
408
409    // here we have to reallocate a new buffer because the buffer could be
410    // used as the front buffer, or by a client in our process
411    // (eg: status bar), and we can't release the handle under its feet.
412    const uint32_t effectiveUsage = getEffectiveUsage(usage);
413    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
414    err = buffer->initCheck();
415
416    if (err || buffer->handle == 0) {
417        GraphicBuffer::dumpAllocationsToSystemLog();
418        LOGE_IF(err || buffer->handle == 0,
419                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
420                this, index, w, h, strerror(-err));
421    } else {
422        LOGD_IF(DEBUG_RESIZE,
423                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
424                this, index, w, h, buffer->handle);
425    }
426
427    if (err == NO_ERROR && buffer->handle != 0) {
428        Mutex::Autolock _l(mLock);
429        mBufferManager.attachBuffer(index, buffer);
430    }
431    return buffer;
432}
433
434uint32_t Layer::getEffectiveUsage(uint32_t usage) const
435{
436    /*
437     *  buffers used for software rendering, but h/w composition
438     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
439     *
440     *  buffers used for h/w rendering and h/w composition
441     *  are allocated with  HW_RENDER | HW_TEXTURE
442     *
443     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
444     *  are allocated with SW_READ_RARELY | HW_RENDER
445     *
446     */
447
448    if (mSecure) {
449        // secure buffer, don't store it into the GPU
450        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
451                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
452    } else {
453        // it's allowed to modify the usage flags here, but generally
454        // the requested flags should be honored.
455        // request EGLImage for all buffers
456        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
457    }
458    return usage;
459}
460
461uint32_t Layer::doTransaction(uint32_t flags)
462{
463    const Layer::State& front(drawingState());
464    const Layer::State& temp(currentState());
465
466    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
467            (front.requested_h != temp.requested_h);
468
469    if (sizeChanged) {
470        // the size changed, we need to ask our client to request a new buffer
471        LOGD_IF(DEBUG_RESIZE,
472                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
473                this,
474                int(temp.requested_w), int(temp.requested_h),
475                int(front.requested_w), int(front.requested_h));
476
477        if (!isFixedSize()) {
478            // we're being resized and there is a freeze display request,
479            // acquire a freeze lock, so that the screen stays put
480            // until we've redrawn at the new size; this is to avoid
481            // glitches upon orientation changes.
482            if (mFlinger->hasFreezeRequest()) {
483                // if the surface is hidden, don't try to acquire the
484                // freeze lock, since hidden surfaces may never redraw
485                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
486                    mFreezeLock = mFlinger->getFreezeLock();
487                }
488            }
489
490            // this will make sure LayerBase::doTransaction doesn't update
491            // the drawing state's size
492            Layer::State& editDraw(mDrawingState);
493            editDraw.requested_w = temp.requested_w;
494            editDraw.requested_h = temp.requested_h;
495
496            // record the new size, form this point on, when the client request
497            // a buffer, it'll get the new size.
498            setBufferSize(temp.requested_w, temp.requested_h);
499
500            ClientRef::Access sharedClient(mUserClientRef);
501            SharedBufferServer* lcblk(sharedClient.get());
502            if (lcblk) {
503                // all buffers need reallocation
504                lcblk->reallocateAll();
505            }
506        } else {
507            // record the new size
508            setBufferSize(temp.requested_w, temp.requested_h);
509        }
510    }
511
512    if (temp.sequence != front.sequence) {
513        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
514            // this surface is now hidden, so it shouldn't hold a freeze lock
515            // (it may never redraw, which is fine if it is hidden)
516            mFreezeLock.clear();
517        }
518    }
519
520    return LayerBase::doTransaction(flags);
521}
522
523void Layer::setBufferSize(uint32_t w, uint32_t h) {
524    Mutex::Autolock _l(mLock);
525    mWidth = w;
526    mHeight = h;
527    mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
528}
529
530bool Layer::isFixedSize() const {
531    Mutex::Autolock _l(mLock);
532    return mFixedSize;
533}
534
535// ----------------------------------------------------------------------------
536// pageflip handling...
537// ----------------------------------------------------------------------------
538
539void Layer::lockPageFlip(bool& recomputeVisibleRegions)
540{
541    ClientRef::Access sharedClient(mUserClientRef);
542    SharedBufferServer* lcblk(sharedClient.get());
543    if (!lcblk) {
544        // client died
545        recomputeVisibleRegions = true;
546        return;
547    }
548
549    ssize_t buf = lcblk->retireAndLock();
550    if (buf == NOT_ENOUGH_DATA) {
551        // NOTE: This is not an error, it simply means there is nothing to
552        // retire. The buffer is locked because we will use it
553        // for composition later in the loop
554        return;
555    }
556
557    if (buf < NO_ERROR) {
558        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
559        mPostedDirtyRegion.clear();
560        return;
561    }
562
563    // we retired a buffer, which becomes the new front buffer
564    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
565        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
566        mPostedDirtyRegion.clear();
567        return;
568    }
569
570    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
571    if (newFrontBuffer != NULL) {
572        // get the dirty region
573        // compute the posted region
574        const Region dirty(lcblk->getDirtyRegion(buf));
575        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
576
577        // update the layer size and release freeze-lock
578        const Layer::State& front(drawingState());
579        if (newFrontBuffer->getWidth()  == front.requested_w &&
580            newFrontBuffer->getHeight() == front.requested_h)
581        {
582            if ((front.w != front.requested_w) ||
583                (front.h != front.requested_h))
584            {
585                // Here we pretend the transaction happened by updating the
586                // current and drawing states. Drawing state is only accessed
587                // in this thread, no need to have it locked
588                Layer::State& editDraw(mDrawingState);
589                editDraw.w = editDraw.requested_w;
590                editDraw.h = editDraw.requested_h;
591
592                // We also need to update the current state so that we don't
593                // end-up doing too much work during the next transaction.
594                // NOTE: We actually don't need hold the transaction lock here
595                // because State::w and State::h are only accessed from
596                // this thread
597                Layer::State& editTemp(currentState());
598                editTemp.w = editDraw.w;
599                editTemp.h = editDraw.h;
600
601                // recompute visible region
602                recomputeVisibleRegions = true;
603            }
604
605            // we now have the correct size, unfreeze the screen
606            mFreezeLock.clear();
607        }
608
609        // get the crop region
610        setBufferCrop( lcblk->getCrop(buf) );
611
612        // get the transformation
613        setBufferTransform( lcblk->getTransform(buf) );
614
615    } else {
616        // this should not happen unless we ran out of memory while
617        // allocating the buffer. we're hoping that things will get back
618        // to normal the next time the app tries to draw into this buffer.
619        // meanwhile, pretend the screen didn't update.
620        mPostedDirtyRegion.clear();
621    }
622
623    if (lcblk->getQueuedCount()) {
624        // signal an event if we have more buffers waiting
625        mFlinger->signalEvent();
626    }
627
628    /* a buffer was posted, so we need to call reloadTexture(), which
629     * will update our internal data structures (eg: EGLImageKHR or
630     * texture names). we need to do this even if mPostedDirtyRegion is
631     * empty -- it's orthogonal to the fact that a new buffer was posted,
632     * for instance, a degenerate case could be that the user did an empty
633     * update but repainted the buffer with appropriate content (after a
634     * resize for instance).
635     */
636    reloadTexture( mPostedDirtyRegion );
637}
638
639void Layer::unlockPageFlip(
640        const Transform& planeTransform, Region& outDirtyRegion)
641{
642    Region dirtyRegion(mPostedDirtyRegion);
643    if (!dirtyRegion.isEmpty()) {
644        mPostedDirtyRegion.clear();
645        // The dirty region is given in the layer's coordinate space
646        // transform the dirty region by the surface's transformation
647        // and the global transformation.
648        const Layer::State& s(drawingState());
649        const Transform tr(planeTransform * s.transform);
650        dirtyRegion = tr.transform(dirtyRegion);
651
652        // At this point, the dirty region is in screen space.
653        // Make sure it's constrained by the visible region (which
654        // is in screen space as well).
655        dirtyRegion.andSelf(visibleRegionScreen);
656        outDirtyRegion.orSelf(dirtyRegion);
657    }
658    if (visibleRegionScreen.isEmpty()) {
659        // an invisible layer should not hold a freeze-lock
660        // (because it may never be updated and therefore never release it)
661        mFreezeLock.clear();
662    }
663}
664
665void Layer::finishPageFlip()
666{
667    ClientRef::Access sharedClient(mUserClientRef);
668    SharedBufferServer* lcblk(sharedClient.get());
669    if (lcblk) {
670        int buf = mBufferManager.getActiveBufferIndex();
671        if (buf >= 0) {
672            status_t err = lcblk->unlock( buf );
673            LOGE_IF(err!=NO_ERROR,
674                    "layer %p, buffer=%d wasn't locked!",
675                    this, buf);
676        }
677    }
678}
679
680
681void Layer::dump(String8& result, char* buffer, size_t SIZE) const
682{
683    LayerBaseClient::dump(result, buffer, SIZE);
684
685    ClientRef::Access sharedClient(mUserClientRef);
686    SharedBufferServer* lcblk(sharedClient.get());
687    uint32_t totalTime = 0;
688    if (lcblk) {
689        SharedBufferStack::Statistics stats = lcblk->getStats();
690        totalTime= stats.totalTime;
691        result.append( lcblk->dump("      ") );
692    }
693
694    sp<const GraphicBuffer> buf0(getBuffer(0));
695    sp<const GraphicBuffer> buf1(getBuffer(1));
696    uint32_t w0=0, h0=0, s0=0;
697    uint32_t w1=0, h1=0, s1=0;
698    if (buf0 != 0) {
699        w0 = buf0->getWidth();
700        h0 = buf0->getHeight();
701        s0 = buf0->getStride();
702    }
703    if (buf1 != 0) {
704        w1 = buf1->getWidth();
705        h1 = buf1->getHeight();
706        s1 = buf1->getStride();
707    }
708    snprintf(buffer, SIZE,
709            "      "
710            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
711            " freezeLock=%p, dq-q-time=%u us\n",
712            mFormat, w0, h0, s0, w1, h1, s1,
713            getFreezeLock().get(), totalTime);
714
715    result.append(buffer);
716}
717
718// ---------------------------------------------------------------------------
719
720Layer::ClientRef::ClientRef()
721    : mControlBlock(0), mToken(-1) {
722}
723
724Layer::ClientRef::~ClientRef() {
725}
726
727int32_t Layer::ClientRef::getToken() const {
728    Mutex::Autolock _l(mLock);
729    return mToken;
730}
731
732sp<UserClient> Layer::ClientRef::getClient() const {
733    Mutex::Autolock _l(mLock);
734    return mUserClient.promote();
735}
736
737status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
738        const sp<SharedBufferServer>& sharedClient, int32_t token) {
739    Mutex::Autolock _l(mLock);
740
741    { // scope for strong mUserClient reference
742        sp<UserClient> userClient(mUserClient.promote());
743        if (mUserClient != 0 && mControlBlock != 0) {
744            mControlBlock->setStatus(NO_INIT);
745        }
746    }
747
748    mUserClient = uc;
749    mToken = token;
750    mControlBlock = sharedClient;
751    return NO_ERROR;
752}
753
754sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
755    return mUserClient.promote();
756}
757
758// this class gives us access to SharedBufferServer safely
759// it makes sure the UserClient (and its associated shared memory)
760// won't go away while we're accessing it.
761Layer::ClientRef::Access::Access(const ClientRef& ref)
762    : mControlBlock(0)
763{
764    Mutex::Autolock _l(ref.mLock);
765    mUserClientStrongRef = ref.mUserClient.promote();
766    if (mUserClientStrongRef != 0)
767        mControlBlock = ref.mControlBlock;
768}
769
770Layer::ClientRef::Access::~Access()
771{
772}
773
774// ---------------------------------------------------------------------------
775
776Layer::BufferManager::BufferManager(TextureManager& tm)
777    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
778      mActiveBuffer(-1), mFailover(false)
779{
780}
781
782Layer::BufferManager::~BufferManager()
783{
784}
785
786status_t Layer::BufferManager::resize(size_t size,
787        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
788{
789    Mutex::Autolock _l(mLock);
790
791    if (size < mNumBuffers) {
792        // Move the active texture into slot 0
793        BufferData activeBufferData = mBufferData[mActiveBuffer];
794        mBufferData[mActiveBuffer] = mBufferData[0];
795        mBufferData[0] = activeBufferData;
796        mActiveBuffer = 0;
797
798        // Free the buffers that are no longer needed.
799        for (size_t i = size; i < mNumBuffers; i++) {
800            mBufferData[i].buffer = 0;
801
802            // Create a message to destroy the textures on SurfaceFlinger's GL
803            // thread.
804            class MessageDestroyTexture : public MessageBase {
805                Image mTexture;
806                EGLDisplay mDpy;
807             public:
808                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
809                    : mTexture(texture), mDpy(dpy) { }
810                virtual bool handler() {
811                    status_t err = Layer::BufferManager::destroyTexture(
812                            &mTexture, mDpy);
813                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
814                            mTexture.name, strerror(-err));
815                    return true; // XXX: err == 0;  ????
816                }
817            };
818
819            MessageDestroyTexture *msg = new MessageDestroyTexture(
820                    mBufferData[i].texture, dpy);
821
822            // Don't allow this texture to be cleaned up by
823            // BufferManager::destroy.
824            mBufferData[i].texture.name = -1U;
825            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
826
827            // Post the message to the SurfaceFlinger object.
828            flinger->postMessageAsync(msg);
829        }
830    }
831
832    mNumBuffers = size;
833    return NO_ERROR;
834}
835
836// only for debugging
837sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
838    return mBufferData[index].buffer;
839}
840
841status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
842    mActiveBuffer = index;
843    return NO_ERROR;
844}
845
846size_t Layer::BufferManager::getActiveBufferIndex() const {
847    return mActiveBuffer;
848}
849
850Texture Layer::BufferManager::getActiveTexture() const {
851    Texture res;
852    if (mFailover || mActiveBuffer<0) {
853        res = mFailoverTexture;
854    } else {
855        static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
856    }
857    return res;
858}
859
860sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
861    sp<GraphicBuffer> result;
862    const ssize_t activeBuffer = mActiveBuffer;
863    if (activeBuffer >= 0) {
864        BufferData const * const buffers = mBufferData;
865        Mutex::Autolock _l(mLock);
866        result = buffers[activeBuffer].buffer;
867    }
868    return result;
869}
870
871sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
872{
873    BufferData* const buffers = mBufferData;
874    sp<GraphicBuffer> buffer;
875    Mutex::Autolock _l(mLock);
876    buffer = buffers[index].buffer;
877    buffers[index].buffer = 0;
878    return buffer;
879}
880
881status_t Layer::BufferManager::attachBuffer(size_t index,
882        const sp<GraphicBuffer>& buffer)
883{
884    BufferData* const buffers = mBufferData;
885    Mutex::Autolock _l(mLock);
886    buffers[index].buffer = buffer;
887    buffers[index].texture.dirty = true;
888    return NO_ERROR;
889}
890
891status_t Layer::BufferManager::destroy(EGLDisplay dpy)
892{
893    BufferData* const buffers = mBufferData;
894    size_t num;
895    { // scope for the lock
896        Mutex::Autolock _l(mLock);
897        num = mNumBuffers;
898        for (size_t i=0 ; i<num ; i++) {
899            buffers[i].buffer = 0;
900        }
901    }
902    for (size_t i=0 ; i<num ; i++) {
903        destroyTexture(&buffers[i].texture, dpy);
904    }
905    destroyTexture(&mFailoverTexture, dpy);
906    return NO_ERROR;
907}
908
909status_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
910        const sp<GraphicBuffer>& buffer)
911{
912    status_t err = NO_INIT;
913    ssize_t index = mActiveBuffer;
914    if (index >= 0) {
915        if (!mFailover) {
916            Image& texture(mBufferData[index].texture);
917            err = mTextureManager.initEglImage(&texture, dpy, buffer);
918            // if EGLImage fails, we switch to regular texture mode, and we
919            // free all resources associated with using EGLImages.
920            if (err == NO_ERROR) {
921                mFailover = false;
922                destroyTexture(&mFailoverTexture, dpy);
923            } else {
924                mFailover = true;
925                const size_t num = mNumBuffers;
926                for (size_t i=0 ; i<num ; i++) {
927                    destroyTexture(&mBufferData[i].texture, dpy);
928                }
929            }
930        } else {
931            // we failed once, don't try again
932            err = BAD_VALUE;
933        }
934    }
935    return err;
936}
937
938status_t Layer::BufferManager::loadTexture(
939        const Region& dirty, const GGLSurface& t)
940{
941    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
942}
943
944status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
945{
946    if (tex->name != -1U) {
947        glDeleteTextures(1, &tex->name);
948        tex->name = -1U;
949    }
950    if (tex->image != EGL_NO_IMAGE_KHR) {
951        eglDestroyImageKHR(dpy, tex->image);
952        tex->image = EGL_NO_IMAGE_KHR;
953    }
954    return NO_ERROR;
955}
956
957// ---------------------------------------------------------------------------
958
959Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
960        const sp<Layer>& owner)
961    : Surface(flinger, owner->getIdentity(), owner)
962{
963}
964
965Layer::SurfaceLayer::~SurfaceLayer()
966{
967}
968
969sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
970        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
971{
972    sp<GraphicBuffer> buffer;
973    sp<Layer> owner(getOwner());
974    if (owner != 0) {
975        /*
976         * requestBuffer() cannot be called from the main thread
977         * as it could cause a dead-lock, since it may have to wait
978         * on conditions updated my the main thread.
979         */
980        buffer = owner->requestBuffer(index, w, h, format, usage);
981    }
982    return buffer;
983}
984
985status_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
986{
987    status_t err = DEAD_OBJECT;
988    sp<Layer> owner(getOwner());
989    if (owner != 0) {
990        /*
991         * setBufferCount() cannot be called from the main thread
992         * as it could cause a dead-lock, since it may have to wait
993         * on conditions updated my the main thread.
994         */
995        err = owner->setBufferCount(bufferCount);
996    }
997    return err;
998}
999
1000// ---------------------------------------------------------------------------
1001
1002
1003}; // namespace android
1004