Home | History | Annotate | Download | only in surfaceflinger_client
      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 #define LOG_TAG "Surface"
     18 
     19 #include <stdint.h>
     20 #include <errno.h>
     21 #include <sys/types.h>
     22 #include <sys/stat.h>
     23 
     24 #include <utils/Errors.h>
     25 #include <utils/threads.h>
     26 #include <utils/CallStack.h>
     27 #include <utils/Log.h>
     28 
     29 #include <binder/IPCThreadState.h>
     30 #include <binder/IMemory.h>
     31 
     32 #include <ui/DisplayInfo.h>
     33 #include <ui/GraphicBuffer.h>
     34 #include <ui/GraphicBufferMapper.h>
     35 #include <ui/GraphicLog.h>
     36 #include <ui/Rect.h>
     37 
     38 #include <surfaceflinger/Surface.h>
     39 #include <surfaceflinger/ISurface.h>
     40 #include <surfaceflinger/ISurfaceComposer.h>
     41 #include <surfaceflinger/SurfaceComposerClient.h>
     42 
     43 #include <private/surfaceflinger/SharedBufferStack.h>
     44 #include <private/surfaceflinger/LayerState.h>
     45 
     46 namespace android {
     47 
     48 // ----------------------------------------------------------------------
     49 
     50 static status_t copyBlt(
     51         const sp<GraphicBuffer>& dst,
     52         const sp<GraphicBuffer>& src,
     53         const Region& reg)
     54 {
     55     // src and dst with, height and format must be identical. no verification
     56     // is done here.
     57     status_t err;
     58     uint8_t const * src_bits = NULL;
     59     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
     60     LOGE_IF(err, "error locking src buffer %s", strerror(-err));
     61 
     62     uint8_t* dst_bits = NULL;
     63     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
     64     LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
     65 
     66     Region::const_iterator head(reg.begin());
     67     Region::const_iterator tail(reg.end());
     68     if (head != tail && src_bits && dst_bits) {
     69         const size_t bpp = bytesPerPixel(src->format);
     70         const size_t dbpr = dst->stride * bpp;
     71         const size_t sbpr = src->stride * bpp;
     72 
     73         while (head != tail) {
     74             const Rect& r(*head++);
     75             ssize_t h = r.height();
     76             if (h <= 0) continue;
     77             size_t size = r.width() * bpp;
     78             uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
     79             uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
     80             if (dbpr==sbpr && size==sbpr) {
     81                 size *= h;
     82                 h = 1;
     83             }
     84             do {
     85                 memcpy(d, s, size);
     86                 d += dbpr;
     87                 s += sbpr;
     88             } while (--h > 0);
     89         }
     90     }
     91 
     92     if (src_bits)
     93         src->unlock();
     94 
     95     if (dst_bits)
     96         dst->unlock();
     97 
     98     return err;
     99 }
    100 
    101 // ============================================================================
    102 //  SurfaceControl
    103 // ============================================================================
    104 
    105 SurfaceControl::SurfaceControl(
    106         const sp<SurfaceComposerClient>& client,
    107         const sp<ISurface>& surface,
    108         const ISurfaceComposerClient::surface_data_t& data,
    109         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
    110     : mClient(client), mSurface(surface),
    111       mToken(data.token), mIdentity(data.identity),
    112       mWidth(data.width), mHeight(data.height), mFormat(data.format),
    113       mFlags(flags)
    114 {
    115 }
    116 
    117 SurfaceControl::~SurfaceControl()
    118 {
    119     destroy();
    120 }
    121 
    122 void SurfaceControl::destroy()
    123 {
    124     if (isValid()) {
    125         mClient->destroySurface(mToken);
    126     }
    127 
    128     // clear all references and trigger an IPC now, to make sure things
    129     // happen without delay, since these resources are quite heavy.
    130     mClient.clear();
    131     mSurface.clear();
    132     IPCThreadState::self()->flushCommands();
    133 }
    134 
    135 void SurfaceControl::clear()
    136 {
    137     // here, the window manager tells us explicitly that we should destroy
    138     // the surface's resource. Soon after this call, it will also release
    139     // its last reference (which will call the dtor); however, it is possible
    140     // that a client living in the same process still holds references which
    141     // would delay the call to the dtor -- that is why we need this explicit
    142     // "clear()" call.
    143     destroy();
    144 }
    145 
    146 bool SurfaceControl::isSameSurface(
    147         const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
    148 {
    149     if (lhs == 0 || rhs == 0)
    150         return false;
    151     return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
    152 }
    153 
    154 status_t SurfaceControl::setLayer(int32_t layer) {
    155     status_t err = validate();
    156     if (err < 0) return err;
    157     const sp<SurfaceComposerClient>& client(mClient);
    158     return client->setLayer(mToken, layer);
    159 }
    160 status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
    161     status_t err = validate();
    162     if (err < 0) return err;
    163     const sp<SurfaceComposerClient>& client(mClient);
    164     return client->setPosition(mToken, x, y);
    165 }
    166 status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
    167     status_t err = validate();
    168     if (err < 0) return err;
    169     const sp<SurfaceComposerClient>& client(mClient);
    170     return client->setSize(mToken, w, h);
    171 }
    172 status_t SurfaceControl::hide() {
    173     status_t err = validate();
    174     if (err < 0) return err;
    175     const sp<SurfaceComposerClient>& client(mClient);
    176     return client->hide(mToken);
    177 }
    178 status_t SurfaceControl::show(int32_t layer) {
    179     status_t err = validate();
    180     if (err < 0) return err;
    181     const sp<SurfaceComposerClient>& client(mClient);
    182     return client->show(mToken, layer);
    183 }
    184 status_t SurfaceControl::freeze() {
    185     status_t err = validate();
    186     if (err < 0) return err;
    187     const sp<SurfaceComposerClient>& client(mClient);
    188     return client->freeze(mToken);
    189 }
    190 status_t SurfaceControl::unfreeze() {
    191     status_t err = validate();
    192     if (err < 0) return err;
    193     const sp<SurfaceComposerClient>& client(mClient);
    194     return client->unfreeze(mToken);
    195 }
    196 status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
    197     status_t err = validate();
    198     if (err < 0) return err;
    199     const sp<SurfaceComposerClient>& client(mClient);
    200     return client->setFlags(mToken, flags, mask);
    201 }
    202 status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
    203     status_t err = validate();
    204     if (err < 0) return err;
    205     const sp<SurfaceComposerClient>& client(mClient);
    206     return client->setTransparentRegionHint(mToken, transparent);
    207 }
    208 status_t SurfaceControl::setAlpha(float alpha) {
    209     status_t err = validate();
    210     if (err < 0) return err;
    211     const sp<SurfaceComposerClient>& client(mClient);
    212     return client->setAlpha(mToken, alpha);
    213 }
    214 status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    215     status_t err = validate();
    216     if (err < 0) return err;
    217     const sp<SurfaceComposerClient>& client(mClient);
    218     return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
    219 }
    220 status_t SurfaceControl::setFreezeTint(uint32_t tint) {
    221     status_t err = validate();
    222     if (err < 0) return err;
    223     const sp<SurfaceComposerClient>& client(mClient);
    224     return client->setFreezeTint(mToken, tint);
    225 }
    226 
    227 status_t SurfaceControl::validate() const
    228 {
    229     if (mToken<0 || mClient==0) {
    230         LOGE("invalid token (%d, identity=%u) or client (%p)",
    231                 mToken, mIdentity, mClient.get());
    232         return NO_INIT;
    233     }
    234     return NO_ERROR;
    235 }
    236 
    237 status_t SurfaceControl::writeSurfaceToParcel(
    238         const sp<SurfaceControl>& control, Parcel* parcel)
    239 {
    240     sp<ISurface> sur;
    241     uint32_t identity = 0;
    242     uint32_t width = 0;
    243     uint32_t height = 0;
    244     uint32_t format = 0;
    245     uint32_t flags = 0;
    246     if (SurfaceControl::isValid(control)) {
    247         sur      = control->mSurface;
    248         identity = control->mIdentity;
    249         width    = control->mWidth;
    250         height   = control->mHeight;
    251         format   = control->mFormat;
    252         flags    = control->mFlags;
    253     }
    254     parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
    255     parcel->writeInt32(identity);
    256     parcel->writeInt32(width);
    257     parcel->writeInt32(height);
    258     parcel->writeInt32(format);
    259     parcel->writeInt32(flags);
    260     return NO_ERROR;
    261 }
    262 
    263 sp<Surface> SurfaceControl::getSurface() const
    264 {
    265     Mutex::Autolock _l(mLock);
    266     if (mSurfaceData == 0) {
    267         mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
    268     }
    269     return mSurfaceData;
    270 }
    271 
    272 // ============================================================================
    273 //  Surface
    274 // ============================================================================
    275 
    276 class SurfaceClient : public Singleton<SurfaceClient>
    277 {
    278     // all these attributes are constants
    279     sp<ISurfaceComposer> mComposerService;
    280     sp<ISurfaceComposerClient> mClient;
    281     status_t mStatus;
    282     SharedClient* mControl;
    283     sp<IMemoryHeap> mControlMemory;
    284 
    285     SurfaceClient()
    286         : Singleton<SurfaceClient>(), mStatus(NO_INIT)
    287     {
    288         sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    289         mComposerService = sf;
    290         mClient = sf->createClientConnection();
    291         if (mClient != NULL) {
    292             mControlMemory = mClient->getControlBlock();
    293             if (mControlMemory != NULL) {
    294                 mControl = static_cast<SharedClient *>(
    295                         mControlMemory->getBase());
    296                 if (mControl) {
    297                     mStatus = NO_ERROR;
    298                 }
    299             }
    300         }
    301     }
    302     friend class Singleton<SurfaceClient>;
    303 public:
    304     status_t initCheck() const {
    305         return mStatus;
    306     }
    307     SharedClient* getSharedClient() const {
    308         return mControl;
    309     }
    310     ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
    311         // TODO: we could cache a few tokens here to avoid an IPC
    312         return mClient->getTokenForSurface(sur);
    313     }
    314     void signalServer() const {
    315         mComposerService->signal();
    316     }
    317 };
    318 
    319 ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
    320 
    321 // ---------------------------------------------------------------------------
    322 
    323 Surface::Surface(const sp<SurfaceControl>& surface)
    324     : mBufferMapper(GraphicBufferMapper::get()),
    325       mClient(SurfaceClient::getInstance()),
    326       mSharedBufferClient(NULL),
    327       mInitCheck(NO_INIT),
    328       mSurface(surface->mSurface),
    329       mIdentity(surface->mIdentity),
    330       mFormat(surface->mFormat), mFlags(surface->mFlags),
    331       mWidth(surface->mWidth), mHeight(surface->mHeight)
    332 {
    333     init();
    334 }
    335 
    336 Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
    337     : mBufferMapper(GraphicBufferMapper::get()),
    338       mClient(SurfaceClient::getInstance()),
    339       mSharedBufferClient(NULL),
    340       mInitCheck(NO_INIT)
    341 {
    342     mSurface    = interface_cast<ISurface>(ref);
    343     mIdentity   = parcel.readInt32();
    344     mWidth      = parcel.readInt32();
    345     mHeight     = parcel.readInt32();
    346     mFormat     = parcel.readInt32();
    347     mFlags      = parcel.readInt32();
    348     init();
    349 }
    350 
    351 status_t Surface::writeToParcel(
    352         const sp<Surface>& surface, Parcel* parcel)
    353 {
    354     sp<ISurface> sur;
    355     uint32_t identity = 0;
    356     uint32_t width = 0;
    357     uint32_t height = 0;
    358     uint32_t format = 0;
    359     uint32_t flags = 0;
    360     if (Surface::isValid(surface)) {
    361         sur      = surface->mSurface;
    362         identity = surface->mIdentity;
    363         width    = surface->mWidth;
    364         height   = surface->mHeight;
    365         format   = surface->mFormat;
    366         flags    = surface->mFlags;
    367     }
    368     parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
    369     parcel->writeInt32(identity);
    370     parcel->writeInt32(width);
    371     parcel->writeInt32(height);
    372     parcel->writeInt32(format);
    373     parcel->writeInt32(flags);
    374     return NO_ERROR;
    375 
    376 }
    377 
    378 
    379 Mutex Surface::sCachedSurfacesLock;
    380 DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
    381 
    382 sp<Surface> Surface::readFromParcel(const Parcel& data) {
    383     Mutex::Autolock _l(sCachedSurfacesLock);
    384     sp<IBinder> binder(data.readStrongBinder());
    385     sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
    386     if (surface == 0) {
    387        surface = new Surface(data, binder);
    388        sCachedSurfaces.add(binder, surface);
    389     }
    390     if (surface->mSurface == 0) {
    391       surface = 0;
    392     }
    393     cleanCachedSurfaces();
    394     return surface;
    395 }
    396 
    397 // Remove the stale entries from the surface cache.  This should only be called
    398 // with sCachedSurfacesLock held.
    399 void Surface::cleanCachedSurfaces() {
    400     for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
    401         wp<Surface> s(sCachedSurfaces.valueAt(i));
    402         if (s == 0 || s.promote() == 0) {
    403             sCachedSurfaces.removeItemsAt(i);
    404         }
    405     }
    406 }
    407 
    408 void Surface::init()
    409 {
    410     ANativeWindow::setSwapInterval  = setSwapInterval;
    411     ANativeWindow::dequeueBuffer    = dequeueBuffer;
    412     ANativeWindow::cancelBuffer     = cancelBuffer;
    413     ANativeWindow::lockBuffer       = lockBuffer;
    414     ANativeWindow::queueBuffer      = queueBuffer;
    415     ANativeWindow::query            = query;
    416     ANativeWindow::perform          = perform;
    417 
    418     DisplayInfo dinfo;
    419     SurfaceComposerClient::getDisplayInfo(0, &dinfo);
    420     const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
    421     const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
    422     // FIXME: set real values here
    423     const_cast<int&>(ANativeWindow::minSwapInterval) = 1;
    424     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
    425     const_cast<uint32_t&>(ANativeWindow::flags) = 0;
    426 
    427     mNextBufferTransform = 0;
    428     mConnected = 0;
    429     mSwapRectangle.makeInvalid();
    430     mNextBufferCrop = Rect(0,0);
    431     // two buffers by default
    432     mBuffers.setCapacity(2);
    433     mBuffers.insertAt(0, 2);
    434 
    435     if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
    436         int32_t token = mClient.getTokenForSurface(mSurface);
    437         if (token >= 0) {
    438             mSharedBufferClient = new SharedBufferClient(
    439                     mClient.getSharedClient(), token, 2, mIdentity);
    440             mInitCheck = mClient.getSharedClient()->validate(token);
    441         }
    442     }
    443 }
    444 
    445 Surface::~Surface()
    446 {
    447     // this is a client-side operation, the surface is destroyed, unmap
    448     // its buffers in this process.
    449     size_t size = mBuffers.size();
    450     for (size_t i=0 ; i<size ; i++) {
    451         if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
    452             getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
    453         }
    454     }
    455 
    456     // clear all references and trigger an IPC now, to make sure things
    457     // happen without delay, since these resources are quite heavy.
    458     mBuffers.clear();
    459     mSurface.clear();
    460     delete mSharedBufferClient;
    461     IPCThreadState::self()->flushCommands();
    462 }
    463 
    464 bool Surface::isValid() {
    465     return mInitCheck == NO_ERROR;
    466 }
    467 
    468 status_t Surface::validate() const
    469 {
    470     // check that we initialized ourself properly
    471     if (mInitCheck != NO_ERROR) {
    472         LOGE("invalid token (identity=%u)", mIdentity);
    473         return mInitCheck;
    474     }
    475 
    476     // verify the identity of this surface
    477     uint32_t identity = mSharedBufferClient->getIdentity();
    478 
    479     // this is a bit of a (temporary) special case, identity==0 means that
    480     // no operation are allowed from the client (eg: dequeue/queue), this
    481     // is used with PUSH_BUFFER surfaces for instance
    482     if (identity == 0) {
    483         LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
    484         return INVALID_OPERATION;
    485     }
    486 
    487     if (mIdentity != identity) {
    488         LOGE("[Surface] using an invalid surface, "
    489                 "identity=%u should be %d",
    490                 mIdentity, identity);
    491         return NO_INIT;
    492     }
    493 
    494     // check the surface didn't become invalid
    495     status_t err = mSharedBufferClient->getStatus();
    496     if (err != NO_ERROR) {
    497         LOGE("surface (identity=%u) is invalid, err=%d (%s)",
    498                 mIdentity, err, strerror(-err));
    499         return err;
    500     }
    501 
    502     return NO_ERROR;
    503 }
    504 
    505 sp<ISurface> Surface::getISurface() const {
    506     return mSurface;
    507 }
    508 
    509 // ----------------------------------------------------------------------------
    510 
    511 int Surface::setSwapInterval(ANativeWindow* window, int interval) {
    512     return 0;
    513 }
    514 
    515 int Surface::dequeueBuffer(ANativeWindow* window,
    516         android_native_buffer_t** buffer) {
    517     Surface* self = getSelf(window);
    518     return self->dequeueBuffer(buffer);
    519 }
    520 
    521 int Surface::cancelBuffer(ANativeWindow* window,
    522         android_native_buffer_t* buffer) {
    523     Surface* self = getSelf(window);
    524     return self->cancelBuffer(buffer);
    525 }
    526 
    527 int Surface::lockBuffer(ANativeWindow* window,
    528         android_native_buffer_t* buffer) {
    529     Surface* self = getSelf(window);
    530     return self->lockBuffer(buffer);
    531 }
    532 
    533 int Surface::queueBuffer(ANativeWindow* window,
    534         android_native_buffer_t* buffer) {
    535     Surface* self = getSelf(window);
    536     return self->queueBuffer(buffer);
    537 }
    538 
    539 int Surface::query(ANativeWindow* window,
    540         int what, int* value) {
    541     Surface* self = getSelf(window);
    542     return self->query(what, value);
    543 }
    544 
    545 int Surface::perform(ANativeWindow* window,
    546         int operation, ...) {
    547     va_list args;
    548     va_start(args, operation);
    549     Surface* self = getSelf(window);
    550     int res = self->perform(operation, args);
    551     va_end(args);
    552     return res;
    553 }
    554 
    555 // ----------------------------------------------------------------------------
    556 
    557 bool Surface::needNewBuffer(int bufIdx,
    558         uint32_t *pWidth, uint32_t *pHeight,
    559         uint32_t *pFormat, uint32_t *pUsage) const
    560 {
    561     Mutex::Autolock _l(mSurfaceLock);
    562 
    563     // Always call needNewBuffer(), since it clears the needed buffers flags
    564     bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
    565     bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
    566     bool newNeewBuffer = needNewBuffer || !validBuffer;
    567     if (newNeewBuffer) {
    568         mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
    569     }
    570     return newNeewBuffer;
    571 }
    572 
    573 int Surface::dequeueBuffer(android_native_buffer_t** buffer)
    574 {
    575     status_t err = validate();
    576     if (err != NO_ERROR)
    577         return err;
    578 
    579     GraphicLog& logger(GraphicLog::getInstance());
    580     logger.log(GraphicLog::SF_APP_DEQUEUE_BEFORE, mIdentity, -1);
    581 
    582     ssize_t bufIdx = mSharedBufferClient->dequeue();
    583 
    584     logger.log(GraphicLog::SF_APP_DEQUEUE_AFTER, mIdentity, bufIdx);
    585 
    586     if (bufIdx < 0) {
    587         LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
    588         return bufIdx;
    589     }
    590 
    591     // grow the buffer array if needed
    592     const size_t size = mBuffers.size();
    593     const size_t needed = bufIdx+1;
    594     if (size < needed) {
    595         mBuffers.insertAt(size, needed-size);
    596     }
    597 
    598     uint32_t w, h, format, usage;
    599     if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
    600         err = getBufferLocked(bufIdx, w, h, format, usage);
    601         LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
    602                 bufIdx, w, h, format, usage, strerror(-err));
    603         if (err == NO_ERROR) {
    604             // reset the width/height with the what we get from the buffer
    605             const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
    606             mWidth  = uint32_t(backBuffer->width);
    607             mHeight = uint32_t(backBuffer->height);
    608         }
    609     }
    610 
    611     // if we still don't have a buffer here, we probably ran out of memory
    612     const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
    613     if (!err && backBuffer==0) {
    614         err = NO_MEMORY;
    615     }
    616 
    617     if (err == NO_ERROR) {
    618         mDirtyRegion.set(backBuffer->width, backBuffer->height);
    619         *buffer = backBuffer.get();
    620     } else {
    621         mSharedBufferClient->undoDequeue(bufIdx);
    622     }
    623 
    624     return err;
    625 }
    626 
    627 int Surface::cancelBuffer(android_native_buffer_t* buffer)
    628 {
    629     status_t err = validate();
    630     switch (err) {
    631     case NO_ERROR:
    632         // no error, common case
    633         break;
    634     case INVALID_OPERATION:
    635         // legitimate errors here
    636         return err;
    637     default:
    638         // other errors happen because the surface is now invalid,
    639         // for instance because it has been destroyed. In this case,
    640         // we just fail silently (canceling a buffer is not technically
    641         // an error at this point)
    642         return NO_ERROR;
    643     }
    644 
    645     int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
    646 
    647     err = mSharedBufferClient->cancel(bufIdx);
    648 
    649     LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
    650     return err;
    651 }
    652 
    653 
    654 int Surface::lockBuffer(android_native_buffer_t* buffer)
    655 {
    656     status_t err = validate();
    657     if (err != NO_ERROR)
    658         return err;
    659 
    660     int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
    661 
    662     GraphicLog& logger(GraphicLog::getInstance());
    663     logger.log(GraphicLog::SF_APP_LOCK_BEFORE, mIdentity, bufIdx);
    664 
    665     err = mSharedBufferClient->lock(bufIdx);
    666 
    667     logger.log(GraphicLog::SF_APP_LOCK_AFTER, mIdentity, bufIdx);
    668 
    669     LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
    670     return err;
    671 }
    672 
    673 int Surface::queueBuffer(android_native_buffer_t* buffer)
    674 {
    675     status_t err = validate();
    676     if (err != NO_ERROR)
    677         return err;
    678 
    679     if (mSwapRectangle.isValid()) {
    680         mDirtyRegion.set(mSwapRectangle);
    681     }
    682 
    683     int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
    684 
    685     GraphicLog::getInstance().log(GraphicLog::SF_APP_QUEUE, mIdentity, bufIdx);
    686 
    687     mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform);
    688     mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
    689     mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
    690     err = mSharedBufferClient->queue(bufIdx);
    691     LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
    692 
    693     if (err == NO_ERROR) {
    694         // TODO: can we avoid this IPC if we know there is one pending?
    695         mClient.signalServer();
    696     }
    697     return err;
    698 }
    699 
    700 int Surface::query(int what, int* value)
    701 {
    702     switch (what) {
    703     case NATIVE_WINDOW_WIDTH:
    704         *value = int(mWidth);
    705         return NO_ERROR;
    706     case NATIVE_WINDOW_HEIGHT:
    707         *value = int(mHeight);
    708         return NO_ERROR;
    709     case NATIVE_WINDOW_FORMAT:
    710         *value = int(mFormat);
    711         return NO_ERROR;
    712     }
    713     return BAD_VALUE;
    714 }
    715 
    716 int Surface::perform(int operation, va_list args)
    717 {
    718     status_t err = validate();
    719     if (err != NO_ERROR)
    720         return err;
    721 
    722     int res = NO_ERROR;
    723     switch (operation) {
    724     case NATIVE_WINDOW_SET_USAGE:
    725         dispatch_setUsage( args );
    726         break;
    727     case NATIVE_WINDOW_CONNECT:
    728         res = dispatch_connect( args );
    729         break;
    730     case NATIVE_WINDOW_DISCONNECT:
    731         res = dispatch_disconnect( args );
    732         break;
    733     case NATIVE_WINDOW_SET_CROP:
    734         res = dispatch_crop( args );
    735         break;
    736     case NATIVE_WINDOW_SET_BUFFER_COUNT:
    737         res = dispatch_set_buffer_count( args );
    738         break;
    739     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
    740         res = dispatch_set_buffers_geometry( args );
    741         break;
    742     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
    743         res = dispatch_set_buffers_transform( args );
    744         break;
    745     default:
    746         res = NAME_NOT_FOUND;
    747         break;
    748     }
    749     return res;
    750 }
    751 
    752 void Surface::dispatch_setUsage(va_list args) {
    753     int usage = va_arg(args, int);
    754     setUsage( usage );
    755 }
    756 int Surface::dispatch_connect(va_list args) {
    757     int api = va_arg(args, int);
    758     return connect( api );
    759 }
    760 int Surface::dispatch_disconnect(va_list args) {
    761     int api = va_arg(args, int);
    762     return disconnect( api );
    763 }
    764 int Surface::dispatch_crop(va_list args) {
    765     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
    766     return crop( reinterpret_cast<Rect const*>(rect) );
    767 }
    768 int Surface::dispatch_set_buffer_count(va_list args) {
    769     size_t bufferCount = va_arg(args, size_t);
    770     return setBufferCount(bufferCount);
    771 }
    772 int Surface::dispatch_set_buffers_geometry(va_list args) {
    773     int w = va_arg(args, int);
    774     int h = va_arg(args, int);
    775     int f = va_arg(args, int);
    776     return setBuffersGeometry(w, h, f);
    777 }
    778 
    779 int Surface::dispatch_set_buffers_transform(va_list args) {
    780     int transform = va_arg(args, int);
    781     return setBuffersTransform(transform);
    782 }
    783 
    784 void Surface::setUsage(uint32_t reqUsage)
    785 {
    786     Mutex::Autolock _l(mSurfaceLock);
    787     mBufferInfo.set(reqUsage);
    788 }
    789 
    790 int Surface::connect(int api)
    791 {
    792     Mutex::Autolock _l(mSurfaceLock);
    793     int err = NO_ERROR;
    794     switch (api) {
    795         case NATIVE_WINDOW_API_EGL:
    796             if (mConnected) {
    797                 err = -EINVAL;
    798             } else {
    799                 mConnected = api;
    800             }
    801             break;
    802         default:
    803             err = -EINVAL;
    804             break;
    805     }
    806     return err;
    807 }
    808 
    809 int Surface::disconnect(int api)
    810 {
    811     Mutex::Autolock _l(mSurfaceLock);
    812     int err = NO_ERROR;
    813     switch (api) {
    814         case NATIVE_WINDOW_API_EGL:
    815             if (mConnected == api) {
    816                 mConnected = 0;
    817             } else {
    818                 err = -EINVAL;
    819             }
    820             break;
    821         default:
    822             err = -EINVAL;
    823             break;
    824     }
    825     return err;
    826 }
    827 
    828 int Surface::crop(Rect const* rect)
    829 {
    830     // empty/invalid rects are not allowed
    831     if (rect->isEmpty())
    832         return BAD_VALUE;
    833 
    834     Mutex::Autolock _l(mSurfaceLock);
    835     // TODO: validate rect size
    836     mNextBufferCrop = *rect;
    837     return NO_ERROR;
    838 }
    839 
    840 int Surface::setBufferCount(int bufferCount)
    841 {
    842     sp<ISurface> s(mSurface);
    843     if (s == 0) return NO_INIT;
    844 
    845     class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
    846         sp<ISurface> surface;
    847         virtual status_t operator()(int bufferCount) const {
    848             return surface->setBufferCount(bufferCount);
    849         }
    850     public:
    851         SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
    852     } ipc(s);
    853 
    854     status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
    855     LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
    856             bufferCount, strerror(-err));
    857     return err;
    858 }
    859 
    860 int Surface::setBuffersGeometry(int w, int h, int format)
    861 {
    862     if (w<0 || h<0 || format<0)
    863         return BAD_VALUE;
    864 
    865     if ((w && !h) || (!w && h))
    866         return BAD_VALUE;
    867 
    868     Mutex::Autolock _l(mSurfaceLock);
    869     if (mConnected == NATIVE_WINDOW_API_EGL) {
    870         return INVALID_OPERATION;
    871     }
    872 
    873     mBufferInfo.set(w, h, format);
    874     if (format != 0) {
    875         // we update the format of the surface as reported by query().
    876         // this is to allow applications to change the format of a surface's
    877         // buffer, and have it reflected in EGL; which is needed for
    878         // EGLConfig validation.
    879         mFormat = format;
    880     }
    881     return NO_ERROR;
    882 }
    883 
    884 int Surface::setBuffersTransform(int transform)
    885 {
    886     Mutex::Autolock _l(mSurfaceLock);
    887     mNextBufferTransform = transform;
    888     return NO_ERROR;
    889 }
    890 
    891 // ----------------------------------------------------------------------------
    892 
    893 int Surface::getConnectedApi() const
    894 {
    895     Mutex::Autolock _l(mSurfaceLock);
    896     return mConnected;
    897 }
    898 
    899 // ----------------------------------------------------------------------------
    900 
    901 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
    902     return Surface::lock(info, NULL, blocking);
    903 }
    904 
    905 status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
    906 {
    907     if (getConnectedApi()) {
    908         LOGE("Surface::lock(%p) failed. Already connected to another API",
    909                 (ANativeWindow*)this);
    910         CallStack stack;
    911         stack.update();
    912         stack.dump("");
    913         return INVALID_OPERATION;
    914     }
    915 
    916     if (mApiLock.tryLock() != NO_ERROR) {
    917         LOGE("calling Surface::lock from different threads!");
    918         CallStack stack;
    919         stack.update();
    920         stack.dump("");
    921         return WOULD_BLOCK;
    922     }
    923 
    924     /* Here we're holding mApiLock */
    925 
    926     if (mLockedBuffer != 0) {
    927         LOGE("Surface::lock failed, already locked");
    928         mApiLock.unlock();
    929         return INVALID_OPERATION;
    930     }
    931 
    932     // we're intending to do software rendering from this point
    933     setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
    934 
    935     android_native_buffer_t* out;
    936     status_t err = dequeueBuffer(&out);
    937     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
    938     if (err == NO_ERROR) {
    939         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
    940         err = lockBuffer(backBuffer.get());
    941         LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
    942                 getBufferIndex(backBuffer), strerror(-err));
    943         if (err == NO_ERROR) {
    944             const Rect bounds(backBuffer->width, backBuffer->height);
    945             const Region boundsRegion(bounds);
    946             Region scratch(boundsRegion);
    947             Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
    948             newDirtyRegion &= boundsRegion;
    949 
    950             // figure out if we can copy the frontbuffer back
    951             const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
    952             const bool canCopyBack = (frontBuffer != 0 &&
    953                     backBuffer->width  == frontBuffer->width &&
    954                     backBuffer->height == frontBuffer->height &&
    955                     backBuffer->format == frontBuffer->format &&
    956                     !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
    957 
    958             // the dirty region we report to surfaceflinger is the one
    959             // given by the user (as opposed to the one *we* return to the
    960             // user).
    961             mDirtyRegion = newDirtyRegion;
    962 
    963             if (canCopyBack) {
    964                 // copy the area that is invalid and not repainted this round
    965                 const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
    966                 if (!copyback.isEmpty())
    967                     copyBlt(backBuffer, frontBuffer, copyback);
    968             } else {
    969                 // if we can't copy-back anything, modify the user's dirty
    970                 // region to make sure they redraw the whole buffer
    971                 newDirtyRegion = boundsRegion;
    972             }
    973 
    974             // keep track of the are of the buffer that is "clean"
    975             // (ie: that will be redrawn)
    976             mOldDirtyRegion = newDirtyRegion;
    977 
    978             void* vaddr;
    979             status_t res = backBuffer->lock(
    980                     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
    981                     newDirtyRegion.bounds(), &vaddr);
    982 
    983             LOGW_IF(res, "failed locking buffer (handle = %p)",
    984                     backBuffer->handle);
    985 
    986             mLockedBuffer = backBuffer;
    987             other->w      = backBuffer->width;
    988             other->h      = backBuffer->height;
    989             other->s      = backBuffer->stride;
    990             other->usage  = backBuffer->usage;
    991             other->format = backBuffer->format;
    992             other->bits   = vaddr;
    993         }
    994     }
    995     mApiLock.unlock();
    996     return err;
    997 }
    998 
    999 status_t Surface::unlockAndPost()
   1000 {
   1001     if (mLockedBuffer == 0) {
   1002         LOGE("Surface::unlockAndPost failed, no locked buffer");
   1003         return INVALID_OPERATION;
   1004     }
   1005 
   1006     status_t err = mLockedBuffer->unlock();
   1007     LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
   1008 
   1009     err = queueBuffer(mLockedBuffer.get());
   1010     LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
   1011             getBufferIndex(mLockedBuffer), strerror(-err));
   1012 
   1013     mPostedBuffer = mLockedBuffer;
   1014     mLockedBuffer = 0;
   1015     return err;
   1016 }
   1017 
   1018 void Surface::setSwapRectangle(const Rect& r) {
   1019     Mutex::Autolock _l(mSurfaceLock);
   1020     mSwapRectangle = r;
   1021 }
   1022 
   1023 int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
   1024 {
   1025     return buffer->getIndex();
   1026 }
   1027 
   1028 status_t Surface::getBufferLocked(int index,
   1029         uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
   1030 {
   1031     sp<ISurface> s(mSurface);
   1032     if (s == 0) return NO_INIT;
   1033 
   1034     status_t err = NO_MEMORY;
   1035 
   1036     // free the current buffer
   1037     sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
   1038     if (currentBuffer != 0) {
   1039         getBufferMapper().unregisterBuffer(currentBuffer->handle);
   1040         currentBuffer.clear();
   1041     }
   1042 
   1043     sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
   1044     LOGE_IF(buffer==0,
   1045             "ISurface::getBuffer(%d, %08x) returned NULL",
   1046             index, usage);
   1047     if (buffer != 0) { // this should never happen by construction
   1048         LOGE_IF(buffer->handle == NULL,
   1049                 "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
   1050                 "returned a buffer with a null handle",
   1051                 mIdentity, index, w, h, format, usage);
   1052         err = mSharedBufferClient->getStatus();
   1053         LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
   1054         if (!err && buffer->handle != NULL) {
   1055             err = getBufferMapper().registerBuffer(buffer->handle);
   1056             LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
   1057                     err, strerror(-err));
   1058             if (err == NO_ERROR) {
   1059                 currentBuffer = buffer;
   1060                 currentBuffer->setIndex(index);
   1061             }
   1062         } else {
   1063             err = err<0 ? err : status_t(NO_MEMORY);
   1064         }
   1065     }
   1066     return err;
   1067 }
   1068 
   1069 // ----------------------------------------------------------------------------
   1070 Surface::BufferInfo::BufferInfo()
   1071     : mWidth(0), mHeight(0), mFormat(0),
   1072       mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
   1073 {
   1074 }
   1075 
   1076 void Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
   1077     if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
   1078         mWidth = w;
   1079         mHeight = h;
   1080         mFormat = format;
   1081         mDirty |= GEOMETRY;
   1082     }
   1083 }
   1084 
   1085 void Surface::BufferInfo::set(uint32_t usage) {
   1086     mUsage = usage;
   1087 }
   1088 
   1089 void Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
   1090         uint32_t *pFormat, uint32_t *pUsage) const {
   1091     *pWidth  = mWidth;
   1092     *pHeight = mHeight;
   1093     *pFormat = mFormat;
   1094     *pUsage  = mUsage;
   1095 }
   1096 
   1097 bool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
   1098     // make sure we AT LEAST have the usage flags we want
   1099     if (mDirty || buffer==0 ||
   1100             ((buffer->usage & mUsage) != mUsage)) {
   1101         mDirty = 0;
   1102         return false;
   1103     }
   1104     return true;
   1105 }
   1106 
   1107 // ----------------------------------------------------------------------------
   1108 }; // namespace android
   1109