Home | History | Annotate | Download | only in surfaceflinger
      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 <utils/Errors.h>
     22 #include <utils/Log.h>
     23 #include <binder/IPCThreadState.h>
     24 #include <binder/IServiceManager.h>
     25 
     26 #include <GLES/gl.h>
     27 #include <GLES/glext.h>
     28 
     29 #include <hardware/hardware.h>
     30 
     31 #include "clz.h"
     32 #include "LayerBase.h"
     33 #include "SurfaceFlinger.h"
     34 #include "DisplayHardware/DisplayHardware.h"
     35 #include "TextureManager.h"
     36 
     37 
     38 namespace android {
     39 
     40 // ---------------------------------------------------------------------------
     41 
     42 int32_t LayerBase::sSequence = 1;
     43 
     44 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     45     : dpy(display), contentDirty(false),
     46       sequence(uint32_t(android_atomic_inc(&sSequence))),
     47       mFlinger(flinger),
     48       mNeedsFiltering(false),
     49       mOrientation(0),
     50       mLeft(0), mTop(0),
     51       mTransactionFlags(0),
     52       mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
     53       mInvalidate(0)
     54 {
     55     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
     56     mFlags = hw.getFlags();
     57     mBufferCrop.makeInvalid();
     58     mBufferTransform = 0;
     59 }
     60 
     61 LayerBase::~LayerBase()
     62 {
     63 }
     64 
     65 void LayerBase::setName(const String8& name) {
     66     mName = name;
     67 }
     68 
     69 String8 LayerBase::getName() const {
     70     return mName;
     71 }
     72 
     73 const GraphicPlane& LayerBase::graphicPlane(int dpy) const
     74 {
     75     return mFlinger->graphicPlane(dpy);
     76 }
     77 
     78 GraphicPlane& LayerBase::graphicPlane(int dpy)
     79 {
     80     return mFlinger->graphicPlane(dpy);
     81 }
     82 
     83 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
     84 {
     85     uint32_t layerFlags = 0;
     86     if (flags & ISurfaceComposer::eHidden)
     87         layerFlags = ISurfaceComposer::eLayerHidden;
     88 
     89     if (flags & ISurfaceComposer::eNonPremultiplied)
     90         mPremultipliedAlpha = false;
     91 
     92     mCurrentState.z             = 0;
     93     mCurrentState.w             = w;
     94     mCurrentState.h             = h;
     95     mCurrentState.requested_w   = w;
     96     mCurrentState.requested_h   = h;
     97     mCurrentState.alpha         = 0xFF;
     98     mCurrentState.flags         = layerFlags;
     99     mCurrentState.sequence      = 0;
    100     mCurrentState.transform.set(0, 0);
    101 
    102     // drawing state & current state are identical
    103     mDrawingState = mCurrentState;
    104 }
    105 
    106 void LayerBase::commitTransaction() {
    107     mDrawingState = mCurrentState;
    108 }
    109 void LayerBase::forceVisibilityTransaction() {
    110     // this can be called without SurfaceFlinger.mStateLock, but if we
    111     // can atomically increment the sequence number, it doesn't matter.
    112     android_atomic_inc(&mCurrentState.sequence);
    113     requestTransaction();
    114 }
    115 bool LayerBase::requestTransaction() {
    116     int32_t old = setTransactionFlags(eTransactionNeeded);
    117     return ((old & eTransactionNeeded) == 0);
    118 }
    119 uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
    120     return android_atomic_and(~flags, &mTransactionFlags) & flags;
    121 }
    122 uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
    123     return android_atomic_or(flags, &mTransactionFlags);
    124 }
    125 
    126 bool LayerBase::setPosition(int32_t x, int32_t y) {
    127     if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
    128         return false;
    129     mCurrentState.sequence++;
    130     mCurrentState.transform.set(x, y);
    131     requestTransaction();
    132     return true;
    133 }
    134 bool LayerBase::setLayer(uint32_t z) {
    135     if (mCurrentState.z == z)
    136         return false;
    137     mCurrentState.sequence++;
    138     mCurrentState.z = z;
    139     requestTransaction();
    140     return true;
    141 }
    142 bool LayerBase::setSize(uint32_t w, uint32_t h) {
    143     if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
    144         return false;
    145     mCurrentState.requested_w = w;
    146     mCurrentState.requested_h = h;
    147     requestTransaction();
    148     return true;
    149 }
    150 bool LayerBase::setAlpha(uint8_t alpha) {
    151     if (mCurrentState.alpha == alpha)
    152         return false;
    153     mCurrentState.sequence++;
    154     mCurrentState.alpha = alpha;
    155     requestTransaction();
    156     return true;
    157 }
    158 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
    159     mCurrentState.sequence++;
    160     mCurrentState.transform.set(
    161             matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
    162     requestTransaction();
    163     return true;
    164 }
    165 bool LayerBase::setTransparentRegionHint(const Region& transparent) {
    166     mCurrentState.sequence++;
    167     mCurrentState.transparentRegion = transparent;
    168     requestTransaction();
    169     return true;
    170 }
    171 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
    172     const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
    173     if (mCurrentState.flags == newFlags)
    174         return false;
    175     mCurrentState.sequence++;
    176     mCurrentState.flags = newFlags;
    177     requestTransaction();
    178     return true;
    179 }
    180 
    181 Rect LayerBase::visibleBounds() const
    182 {
    183     return mTransformedBounds;
    184 }
    185 
    186 void LayerBase::setVisibleRegion(const Region& visibleRegion) {
    187     // always called from main thread
    188     visibleRegionScreen = visibleRegion;
    189 }
    190 
    191 void LayerBase::setCoveredRegion(const Region& coveredRegion) {
    192     // always called from main thread
    193     coveredRegionScreen = coveredRegion;
    194 }
    195 
    196 uint32_t LayerBase::doTransaction(uint32_t flags)
    197 {
    198     const Layer::State& front(drawingState());
    199     const Layer::State& temp(currentState());
    200 
    201     if ((front.requested_w != temp.requested_w) ||
    202         (front.requested_h != temp.requested_h))  {
    203         // resize the layer, set the physical size to the requested size
    204         Layer::State& editTemp(currentState());
    205         editTemp.w = temp.requested_w;
    206         editTemp.h = temp.requested_h;
    207     }
    208 
    209     if ((front.w != temp.w) || (front.h != temp.h)) {
    210         // invalidate and recompute the visible regions if needed
    211         flags |= Layer::eVisibleRegion;
    212     }
    213 
    214     if (temp.sequence != front.sequence) {
    215         // invalidate and recompute the visible regions if needed
    216         flags |= eVisibleRegion;
    217         this->contentDirty = true;
    218 
    219         // we may use linear filtering, if the matrix scales us
    220         const uint8_t type = temp.transform.getType();
    221         mNeedsFiltering = (!temp.transform.preserveRects() ||
    222                 (type >= Transform::SCALE));
    223     }
    224 
    225     // Commit the transaction
    226     commitTransaction();
    227     return flags;
    228 }
    229 
    230 void LayerBase::validateVisibility(const Transform& planeTransform)
    231 {
    232     const Layer::State& s(drawingState());
    233     const Transform tr(planeTransform * s.transform);
    234     const bool transformed = tr.transformed();
    235 
    236     uint32_t w = s.w;
    237     uint32_t h = s.h;
    238     tr.transform(mVertices[0], 0, 0);
    239     tr.transform(mVertices[1], 0, h);
    240     tr.transform(mVertices[2], w, h);
    241     tr.transform(mVertices[3], w, 0);
    242     if (UNLIKELY(transformed)) {
    243         // NOTE: here we could also punt if we have too many rectangles
    244         // in the transparent region
    245         if (tr.preserveRects()) {
    246             // transform the transparent region
    247             transparentRegionScreen = tr.transform(s.transparentRegion);
    248         } else {
    249             // transformation too complex, can't do the transparent region
    250             // optimization.
    251             transparentRegionScreen.clear();
    252         }
    253     } else {
    254         transparentRegionScreen = s.transparentRegion;
    255     }
    256 
    257     // cache a few things...
    258     mOrientation = tr.getOrientation();
    259     mTransformedBounds = tr.makeBounds(w, h);
    260     mLeft = tr.tx();
    261     mTop  = tr.ty();
    262 }
    263 
    264 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
    265 {
    266 }
    267 
    268 void LayerBase::unlockPageFlip(
    269         const Transform& planeTransform, Region& outDirtyRegion)
    270 {
    271     if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
    272         outDirtyRegion.orSelf(visibleRegionScreen);
    273     }
    274 }
    275 
    276 void LayerBase::invalidate()
    277 {
    278     if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
    279         mFlinger->signalEvent();
    280     }
    281 }
    282 
    283 void LayerBase::drawRegion(const Region& reg) const
    284 {
    285     Region::const_iterator it = reg.begin();
    286     Region::const_iterator const end = reg.end();
    287     if (it != end) {
    288         Rect r;
    289         const DisplayHardware& hw(graphicPlane(0).displayHardware());
    290         const int32_t fbWidth  = hw.getWidth();
    291         const int32_t fbHeight = hw.getHeight();
    292         const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
    293                 { fbWidth, fbHeight }, { 0, fbHeight }  };
    294         glVertexPointer(2, GL_SHORT, 0, vertices);
    295         while (it != end) {
    296             const Rect& r = *it++;
    297             const GLint sy = fbHeight - (r.top + r.height());
    298             glScissor(r.left, sy, r.width(), r.height());
    299             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    300         }
    301     }
    302 }
    303 
    304 void LayerBase::draw(const Region& clip) const
    305 {
    306     // reset GL state
    307     glEnable(GL_SCISSOR_TEST);
    308 
    309     onDraw(clip);
    310 }
    311 
    312 void LayerBase::drawForSreenShot() const
    313 {
    314     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    315     onDraw( Region(hw.bounds()) );
    316 }
    317 
    318 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
    319                                 GLclampf green, GLclampf blue,
    320                                 GLclampf alpha) const
    321 {
    322     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    323     const uint32_t fbHeight = hw.getHeight();
    324     glColor4f(red,green,blue,alpha);
    325 
    326     TextureManager::deactivateTextures();
    327 
    328     glDisable(GL_BLEND);
    329     glDisable(GL_DITHER);
    330 
    331     Region::const_iterator it = clip.begin();
    332     Region::const_iterator const end = clip.end();
    333     glEnable(GL_SCISSOR_TEST);
    334     glVertexPointer(2, GL_FLOAT, 0, mVertices);
    335     while (it != end) {
    336         const Rect& r = *it++;
    337         const GLint sy = fbHeight - (r.top + r.height());
    338         glScissor(r.left, sy, r.width(), r.height());
    339         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    340     }
    341 }
    342 
    343 void LayerBase::clearWithOpenGL(const Region& clip) const
    344 {
    345     clearWithOpenGL(clip,0,0,0,0);
    346 }
    347 
    348 template <typename T>
    349 static inline
    350 void swap(T& a, T& b) {
    351     T t(a);
    352     a = b;
    353     b = t;
    354 }
    355 
    356 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
    357 {
    358     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    359     const uint32_t fbHeight = hw.getHeight();
    360     const State& s(drawingState());
    361 
    362     // bind our texture
    363     TextureManager::activateTexture(texture, needsFiltering());
    364     uint32_t width  = texture.width;
    365     uint32_t height = texture.height;
    366 
    367     GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
    368     if (UNLIKELY(s.alpha < 0xFF)) {
    369         const GLfloat alpha = s.alpha * (1.0f/255.0f);
    370         if (mPremultipliedAlpha) {
    371             glColor4f(alpha, alpha, alpha, alpha);
    372         } else {
    373             glColor4f(1, 1, 1, alpha);
    374         }
    375         glEnable(GL_BLEND);
    376         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
    377         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    378     } else {
    379         glColor4f(1, 1, 1, 1);
    380         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    381         if (needsBlending()) {
    382             glEnable(GL_BLEND);
    383             glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
    384         } else {
    385             glDisable(GL_BLEND);
    386         }
    387     }
    388 
    389     /*
    390      *  compute texture coordinates
    391      *  here, we handle NPOT, cropping and buffer transformations
    392      */
    393 
    394     GLfloat cl, ct, cr, cb;
    395     if (!mBufferCrop.isEmpty()) {
    396         // source is cropped
    397         const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width;
    398         const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height;
    399         cl = mBufferCrop.left   * us;
    400         ct = mBufferCrop.top    * vs;
    401         cr = mBufferCrop.right  * us;
    402         cb = mBufferCrop.bottom * vs;
    403     } else {
    404         cl = 0;
    405         ct = 0;
    406         cr = (texture.NPOTAdjust ? texture.wScale : 1.0f);
    407         cb = (texture.NPOTAdjust ? texture.hScale : 1.0f);
    408     }
    409 
    410     /*
    411      * For the buffer transformation, we apply the rotation last.
    412      * Since we're transforming the texture-coordinates, we need
    413      * to apply the inverse of the buffer transformation:
    414      *   inverse( FLIP_V -> FLIP_H -> ROT_90 )
    415      *   <=> inverse( ROT_90 * FLIP_H * FLIP_V )
    416      *    =  inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90)
    417      *    =  FLIP_V * FLIP_H * ROT_270
    418      *   <=> ROT_270 -> FLIP_H -> FLIP_V
    419      *
    420      * The rotation is performed first, in the texture coordinate space.
    421      *
    422      */
    423 
    424     struct TexCoords {
    425         GLfloat u;
    426         GLfloat v;
    427     };
    428 
    429     enum {
    430         // name of the corners in the texture map
    431         LB = 0, // left-bottom
    432         LT = 1, // left-top
    433         RT = 2, // right-top
    434         RB = 3  // right-bottom
    435     };
    436 
    437     // vertices in screen space
    438     int vLT = LB;
    439     int vLB = LT;
    440     int vRB = RT;
    441     int vRT = RB;
    442 
    443     // the texture's source is rotated
    444     uint32_t transform = mBufferTransform;
    445     if (transform & HAL_TRANSFORM_ROT_90) {
    446         vLT = RB;
    447         vLB = LB;
    448         vRB = LT;
    449         vRT = RT;
    450     }
    451     if (transform & HAL_TRANSFORM_FLIP_V) {
    452         swap(vLT, vLB);
    453         swap(vRT, vRB);
    454     }
    455     if (transform & HAL_TRANSFORM_FLIP_H) {
    456         swap(vLT, vRT);
    457         swap(vLB, vRB);
    458     }
    459 
    460     TexCoords texCoords[4];
    461     texCoords[vLT].u = cl;
    462     texCoords[vLT].v = ct;
    463     texCoords[vLB].u = cl;
    464     texCoords[vLB].v = cb;
    465     texCoords[vRB].u = cr;
    466     texCoords[vRB].v = cb;
    467     texCoords[vRT].u = cr;
    468     texCoords[vRT].v = ct;
    469 
    470     if (needsDithering()) {
    471         glEnable(GL_DITHER);
    472     } else {
    473         glDisable(GL_DITHER);
    474     }
    475 
    476     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    477     glVertexPointer(2, GL_FLOAT, 0, mVertices);
    478     glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    479 
    480     Region::const_iterator it = clip.begin();
    481     Region::const_iterator const end = clip.end();
    482     while (it != end) {
    483         const Rect& r = *it++;
    484         const GLint sy = fbHeight - (r.top + r.height());
    485         glScissor(r.left, sy, r.width(), r.height());
    486         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    487     }
    488     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    489 }
    490 
    491 void LayerBase::setBufferCrop(const Rect& crop) {
    492     if (!crop.isEmpty()) {
    493         mBufferCrop = crop;
    494     }
    495 }
    496 
    497 void LayerBase::setBufferTransform(uint32_t transform) {
    498     mBufferTransform = transform;
    499 }
    500 
    501 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
    502 {
    503     const Layer::State& s(drawingState());
    504     snprintf(buffer, SIZE,
    505             "+ %s %p\n"
    506             "      "
    507             "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
    508             "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
    509             "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
    510             getTypeId(), this, s.z, tx(), ty(), s.w, s.h,
    511             needsBlending(), needsDithering(), contentDirty,
    512             s.alpha, s.flags,
    513             s.transform[0][0], s.transform[0][1],
    514             s.transform[1][0], s.transform[1][1]);
    515     result.append(buffer);
    516 }
    517 
    518 // ---------------------------------------------------------------------------
    519 
    520 int32_t LayerBaseClient::sIdentity = 1;
    521 
    522 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
    523         const sp<Client>& client)
    524     : LayerBase(flinger, display), mClientRef(client),
    525       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
    526 {
    527 }
    528 
    529 LayerBaseClient::~LayerBaseClient()
    530 {
    531     sp<Client> c(mClientRef.promote());
    532     if (c != 0) {
    533         c->detachLayer(this);
    534     }
    535 }
    536 
    537 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
    538 {
    539     sp<Surface> s;
    540     Mutex::Autolock _l(mLock);
    541     s = mClientSurface.promote();
    542     if (s == 0) {
    543         s = createSurface();
    544         mClientSurface = s;
    545     }
    546     return s;
    547 }
    548 
    549 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
    550 {
    551     return new Surface(mFlinger, mIdentity,
    552             const_cast<LayerBaseClient *>(this));
    553 }
    554 
    555 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
    556 {
    557     LayerBase::dump(result, buffer, SIZE);
    558 
    559     sp<Client> client(mClientRef.promote());
    560     snprintf(buffer, SIZE,
    561             "      name=%s\n"
    562             "      client=%p, identity=%u\n",
    563             getName().string(),
    564             client.get(), getIdentity());
    565 
    566     result.append(buffer);
    567 }
    568 
    569 // ---------------------------------------------------------------------------
    570 
    571 LayerBaseClient::Surface::Surface(
    572         const sp<SurfaceFlinger>& flinger,
    573         int identity,
    574         const sp<LayerBaseClient>& owner)
    575     : mFlinger(flinger), mIdentity(identity), mOwner(owner)
    576 {
    577 }
    578 
    579 LayerBaseClient::Surface::~Surface()
    580 {
    581     /*
    582      * This is a good place to clean-up all client resources
    583      */
    584 
    585     // destroy client resources
    586     mFlinger->destroySurface(mOwner);
    587 }
    588 
    589 sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
    590     sp<LayerBaseClient> owner(mOwner.promote());
    591     return owner;
    592 }
    593 
    594 status_t LayerBaseClient::Surface::onTransact(
    595         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    596 {
    597     switch (code) {
    598         case REGISTER_BUFFERS:
    599         case UNREGISTER_BUFFERS:
    600         case CREATE_OVERLAY:
    601         {
    602             if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
    603                 IPCThreadState* ipc = IPCThreadState::self();
    604                 const int pid = ipc->getCallingPid();
    605                 const int uid = ipc->getCallingUid();
    606                 LOGE("Permission Denial: "
    607                         "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
    608                 return PERMISSION_DENIED;
    609             }
    610         }
    611     }
    612     return BnSurface::onTransact(code, data, reply, flags);
    613 }
    614 
    615 sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int bufferIdx,
    616         uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
    617 {
    618     return NULL;
    619 }
    620 
    621 status_t LayerBaseClient::Surface::setBufferCount(int bufferCount)
    622 {
    623     return INVALID_OPERATION;
    624 }
    625 
    626 status_t LayerBaseClient::Surface::registerBuffers(
    627         const ISurface::BufferHeap& buffers)
    628 {
    629     return INVALID_OPERATION;
    630 }
    631 
    632 void LayerBaseClient::Surface::postBuffer(ssize_t offset)
    633 {
    634 }
    635 
    636 void LayerBaseClient::Surface::unregisterBuffers()
    637 {
    638 }
    639 
    640 sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
    641         uint32_t w, uint32_t h, int32_t format, int32_t orientation)
    642 {
    643     return NULL;
    644 };
    645 
    646 // ---------------------------------------------------------------------------
    647 
    648 }; // namespace android
    649