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 
     36 namespace android {
     37 
     38 // ---------------------------------------------------------------------------
     39 
     40 int32_t LayerBase::sSequence = 1;
     41 
     42 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     43     : dpy(display), contentDirty(false),
     44       sequence(uint32_t(android_atomic_inc(&sSequence))),
     45       mFlinger(flinger), mFiltering(false),
     46       mNeedsFiltering(false), mInOverlay(false),
     47       mOrientation(0),
     48       mPlaneOrientation(0),
     49       mTransactionFlags(0),
     50       mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
     51       mInvalidate(0)
     52 {
     53     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
     54     mFlags = hw.getFlags();
     55 }
     56 
     57 LayerBase::~LayerBase()
     58 {
     59 }
     60 
     61 void LayerBase::setName(const String8& name) {
     62     mName = name;
     63 }
     64 
     65 String8 LayerBase::getName() const {
     66     return mName;
     67 }
     68 
     69 const GraphicPlane& LayerBase::graphicPlane(int dpy) const
     70 {
     71     return mFlinger->graphicPlane(dpy);
     72 }
     73 
     74 GraphicPlane& LayerBase::graphicPlane(int dpy)
     75 {
     76     return mFlinger->graphicPlane(dpy);
     77 }
     78 
     79 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
     80 {
     81     uint32_t layerFlags = 0;
     82     if (flags & ISurfaceComposer::eHidden)
     83         layerFlags = ISurfaceComposer::eLayerHidden;
     84 
     85     if (flags & ISurfaceComposer::eNonPremultiplied)
     86         mPremultipliedAlpha = false;
     87 
     88     mCurrentState.z             = 0;
     89     mCurrentState.w             = w;
     90     mCurrentState.h             = h;
     91     mCurrentState.requested_w   = w;
     92     mCurrentState.requested_h   = h;
     93     mCurrentState.alpha         = 0xFF;
     94     mCurrentState.flags         = layerFlags;
     95     mCurrentState.sequence      = 0;
     96     mCurrentState.transform.set(0, 0);
     97 
     98     // drawing state & current state are identical
     99     mDrawingState = mCurrentState;
    100 }
    101 
    102 void LayerBase::commitTransaction() {
    103     mDrawingState = mCurrentState;
    104 }
    105 void LayerBase::forceVisibilityTransaction() {
    106     // this can be called without SurfaceFlinger.mStateLock, but if we
    107     // can atomically increment the sequence number, it doesn't matter.
    108     android_atomic_inc(&mCurrentState.sequence);
    109     requestTransaction();
    110 }
    111 bool LayerBase::requestTransaction() {
    112     int32_t old = setTransactionFlags(eTransactionNeeded);
    113     return ((old & eTransactionNeeded) == 0);
    114 }
    115 uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
    116     return android_atomic_and(~flags, &mTransactionFlags) & flags;
    117 }
    118 uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
    119     return android_atomic_or(flags, &mTransactionFlags);
    120 }
    121 
    122 bool LayerBase::setPosition(float x, float y) {
    123     if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
    124         return false;
    125     mCurrentState.sequence++;
    126     mCurrentState.transform.set(x, y);
    127     requestTransaction();
    128     return true;
    129 }
    130 bool LayerBase::setLayer(uint32_t z) {
    131     if (mCurrentState.z == z)
    132         return false;
    133     mCurrentState.sequence++;
    134     mCurrentState.z = z;
    135     requestTransaction();
    136     return true;
    137 }
    138 bool LayerBase::setSize(uint32_t w, uint32_t h) {
    139     if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
    140         return false;
    141     mCurrentState.requested_w = w;
    142     mCurrentState.requested_h = h;
    143     requestTransaction();
    144     return true;
    145 }
    146 bool LayerBase::setAlpha(uint8_t alpha) {
    147     if (mCurrentState.alpha == alpha)
    148         return false;
    149     mCurrentState.sequence++;
    150     mCurrentState.alpha = alpha;
    151     requestTransaction();
    152     return true;
    153 }
    154 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
    155     mCurrentState.sequence++;
    156     mCurrentState.transform.set(
    157             matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
    158     requestTransaction();
    159     return true;
    160 }
    161 bool LayerBase::setTransparentRegionHint(const Region& transparent) {
    162     mCurrentState.sequence++;
    163     mCurrentState.transparentRegion = transparent;
    164     requestTransaction();
    165     return true;
    166 }
    167 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
    168     const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
    169     if (mCurrentState.flags == newFlags)
    170         return false;
    171     mCurrentState.sequence++;
    172     mCurrentState.flags = newFlags;
    173     requestTransaction();
    174     return true;
    175 }
    176 
    177 Rect LayerBase::visibleBounds() const
    178 {
    179     return mTransformedBounds;
    180 }
    181 
    182 void LayerBase::setVisibleRegion(const Region& visibleRegion) {
    183     // always called from main thread
    184     visibleRegionScreen = visibleRegion;
    185 }
    186 
    187 void LayerBase::setCoveredRegion(const Region& coveredRegion) {
    188     // always called from main thread
    189     coveredRegionScreen = coveredRegion;
    190 }
    191 
    192 uint32_t LayerBase::doTransaction(uint32_t flags)
    193 {
    194     const Layer::State& front(drawingState());
    195     const Layer::State& temp(currentState());
    196 
    197     if ((front.requested_w != temp.requested_w) ||
    198         (front.requested_h != temp.requested_h))  {
    199         // resize the layer, set the physical size to the requested size
    200         Layer::State& editTemp(currentState());
    201         editTemp.w = temp.requested_w;
    202         editTemp.h = temp.requested_h;
    203     }
    204 
    205     if ((front.w != temp.w) || (front.h != temp.h)) {
    206         // invalidate and recompute the visible regions if needed
    207         flags |= Layer::eVisibleRegion;
    208     }
    209 
    210     if (temp.sequence != front.sequence) {
    211         // invalidate and recompute the visible regions if needed
    212         flags |= eVisibleRegion;
    213         this->contentDirty = true;
    214 
    215         // we may use linear filtering, if the matrix scales us
    216         const uint8_t type = temp.transform.getType();
    217         mNeedsFiltering = (!temp.transform.preserveRects() ||
    218                 (type >= Transform::SCALE));
    219     }
    220 
    221     // Commit the transaction
    222     commitTransaction();
    223     return flags;
    224 }
    225 
    226 void LayerBase::validateVisibility(const Transform& planeTransform)
    227 {
    228     const Layer::State& s(drawingState());
    229     const Transform tr(planeTransform * s.transform);
    230     const bool transformed = tr.transformed();
    231     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    232     const uint32_t hw_h = hw.getHeight();
    233 
    234     uint32_t w = s.w;
    235     uint32_t h = s.h;
    236     tr.transform(mVertices[0], 0, 0);
    237     tr.transform(mVertices[1], 0, h);
    238     tr.transform(mVertices[2], w, h);
    239     tr.transform(mVertices[3], w, 0);
    240     for (size_t i=0 ; i<4 ; i++)
    241         mVertices[i][1] = hw_h - mVertices[i][1];
    242 
    243     if (UNLIKELY(transformed)) {
    244         // NOTE: here we could also punt if we have too many rectangles
    245         // in the transparent region
    246         if (tr.preserveRects()) {
    247             // transform the transparent region
    248             transparentRegionScreen = tr.transform(s.transparentRegion);
    249         } else {
    250             // transformation too complex, can't do the transparent region
    251             // optimization.
    252             transparentRegionScreen.clear();
    253         }
    254     } else {
    255         transparentRegionScreen = s.transparentRegion;
    256     }
    257 
    258     // cache a few things...
    259     mOrientation = tr.getOrientation();
    260     mPlaneOrientation = planeTransform.getOrientation();
    261     mTransform = tr;
    262     mTransformedBounds = tr.makeBounds(w, h);
    263 }
    264 
    265 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
    266 {
    267 }
    268 
    269 void LayerBase::unlockPageFlip(
    270         const Transform& planeTransform, Region& outDirtyRegion)
    271 {
    272     if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
    273         outDirtyRegion.orSelf(visibleRegionScreen);
    274     }
    275 }
    276 
    277 void LayerBase::invalidate()
    278 {
    279     if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
    280         mFlinger->signalEvent();
    281     }
    282 }
    283 
    284 void LayerBase::drawRegion(const Region& reg) const
    285 {
    286     Region::const_iterator it = reg.begin();
    287     Region::const_iterator const end = reg.end();
    288     if (it != end) {
    289         Rect r;
    290         const DisplayHardware& hw(graphicPlane(0).displayHardware());
    291         const int32_t fbWidth  = hw.getWidth();
    292         const int32_t fbHeight = hw.getHeight();
    293         const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
    294                 { fbWidth, fbHeight }, { 0, fbHeight }  };
    295         glVertexPointer(2, GL_SHORT, 0, vertices);
    296         while (it != end) {
    297             const Rect& r = *it++;
    298             const GLint sy = fbHeight - (r.top + r.height());
    299             glScissor(r.left, sy, r.width(), r.height());
    300             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    301         }
    302     }
    303 }
    304 
    305 void LayerBase::setGeometry(hwc_layer_t* hwcl)
    306 {
    307     hwcl->compositionType = HWC_FRAMEBUFFER;
    308     hwcl->hints = 0;
    309     hwcl->flags = HWC_SKIP_LAYER;
    310     hwcl->transform = 0;
    311     hwcl->blending = HWC_BLENDING_NONE;
    312 
    313     // this gives us only the "orientation" component of the transform
    314     const State& s(drawingState());
    315     const uint32_t finalTransform = s.transform.getOrientation();
    316     // we can only handle simple transformation
    317     if (finalTransform & Transform::ROT_INVALID) {
    318         hwcl->flags = HWC_SKIP_LAYER;
    319     } else {
    320         hwcl->transform = finalTransform;
    321     }
    322 
    323     if (!isOpaque()) {
    324         hwcl->blending = mPremultipliedAlpha ?
    325                 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
    326     }
    327 
    328     // scaling is already applied in mTransformedBounds
    329     hwcl->displayFrame.left   = mTransformedBounds.left;
    330     hwcl->displayFrame.top    = mTransformedBounds.top;
    331     hwcl->displayFrame.right  = mTransformedBounds.right;
    332     hwcl->displayFrame.bottom = mTransformedBounds.bottom;
    333     hwcl->visibleRegionScreen.rects =
    334             reinterpret_cast<hwc_rect_t const *>(
    335                     visibleRegionScreen.getArray(
    336                             &hwcl->visibleRegionScreen.numRects));
    337 
    338     hwcl->sourceCrop.left   = 0;
    339     hwcl->sourceCrop.top    = 0;
    340     hwcl->sourceCrop.right  = mTransformedBounds.width();
    341     hwcl->sourceCrop.bottom = mTransformedBounds.height();
    342 }
    343 
    344 void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
    345     hwcl->compositionType = HWC_FRAMEBUFFER;
    346     hwcl->handle = NULL;
    347 }
    348 
    349 void LayerBase::setOverlay(bool inOverlay) {
    350     mInOverlay = inOverlay;
    351 }
    352 
    353 bool LayerBase::isOverlay() const {
    354     return mInOverlay;
    355 }
    356 
    357 void LayerBase::setFiltering(bool filtering)
    358 {
    359     mFiltering = filtering;
    360 }
    361 
    362 bool LayerBase::getFiltering() const
    363 {
    364     return mFiltering;
    365 }
    366 
    367 void LayerBase::draw(const Region& clip) const
    368 {
    369     // reset GL state
    370     glEnable(GL_SCISSOR_TEST);
    371 
    372     onDraw(clip);
    373 }
    374 
    375 void LayerBase::drawForSreenShot()
    376 {
    377     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    378     setFiltering(true);
    379     onDraw( Region(hw.bounds()) );
    380     setFiltering(false);
    381 }
    382 
    383 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
    384                                 GLclampf green, GLclampf blue,
    385                                 GLclampf alpha) const
    386 {
    387     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    388     const uint32_t fbHeight = hw.getHeight();
    389     glColor4f(red,green,blue,alpha);
    390 
    391     glDisable(GL_TEXTURE_EXTERNAL_OES);
    392     glDisable(GL_TEXTURE_2D);
    393     glDisable(GL_BLEND);
    394 
    395     Region::const_iterator it = clip.begin();
    396     Region::const_iterator const end = clip.end();
    397     glEnable(GL_SCISSOR_TEST);
    398     glVertexPointer(2, GL_FLOAT, 0, mVertices);
    399     while (it != end) {
    400         const Rect& r = *it++;
    401         const GLint sy = fbHeight - (r.top + r.height());
    402         glScissor(r.left, sy, r.width(), r.height());
    403         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    404     }
    405 }
    406 
    407 void LayerBase::clearWithOpenGL(const Region& clip) const
    408 {
    409     clearWithOpenGL(clip,0,0,0,0);
    410 }
    411 
    412 void LayerBase::drawWithOpenGL(const Region& clip) const
    413 {
    414     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    415     const uint32_t fbHeight = hw.getHeight();
    416     const State& s(drawingState());
    417 
    418     GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
    419     if (UNLIKELY(s.alpha < 0xFF)) {
    420         const GLfloat alpha = s.alpha * (1.0f/255.0f);
    421         if (mPremultipliedAlpha) {
    422             glColor4f(alpha, alpha, alpha, alpha);
    423         } else {
    424             glColor4f(1, 1, 1, alpha);
    425         }
    426         glEnable(GL_BLEND);
    427         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
    428         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    429     } else {
    430         glColor4f(1, 1, 1, 1);
    431         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    432         if (!isOpaque()) {
    433             glEnable(GL_BLEND);
    434             glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
    435         } else {
    436             glDisable(GL_BLEND);
    437         }
    438     }
    439 
    440     struct TexCoords {
    441         GLfloat u;
    442         GLfloat v;
    443     };
    444 
    445     TexCoords texCoords[4];
    446     texCoords[0].u = 0;
    447     texCoords[0].v = 1;
    448     texCoords[1].u = 0;
    449     texCoords[1].v = 0;
    450     texCoords[2].u = 1;
    451     texCoords[2].v = 0;
    452     texCoords[3].u = 1;
    453     texCoords[3].v = 1;
    454 
    455     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    456     glVertexPointer(2, GL_FLOAT, 0, mVertices);
    457     glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    458 
    459     Region::const_iterator it = clip.begin();
    460     Region::const_iterator const end = clip.end();
    461     while (it != end) {
    462         const Rect& r = *it++;
    463         const GLint sy = fbHeight - (r.top + r.height());
    464         glScissor(r.left, sy, r.width(), r.height());
    465         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    466     }
    467     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    468     glDisable(GL_BLEND);
    469 }
    470 
    471 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
    472 {
    473     const Layer::State& s(drawingState());
    474     snprintf(buffer, SIZE,
    475             "+ %s %p (%s)\n"
    476             "      "
    477             "z=%9d, pos=(%g,%g), size=(%4d,%4d), "
    478             "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
    479             "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
    480             getTypeId(), this, getName().string(),
    481             s.z, s.transform.tx(), s.transform.ty(), s.w, s.h,
    482             isOpaque(), needsDithering(), contentDirty,
    483             s.alpha, s.flags,
    484             s.transform[0][0], s.transform[0][1],
    485             s.transform[1][0], s.transform[1][1]);
    486     result.append(buffer);
    487 }
    488 
    489 void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
    490 {
    491     LayerBase::dump(result, scratch, size);
    492 }
    493 
    494 
    495 // ---------------------------------------------------------------------------
    496 
    497 int32_t LayerBaseClient::sIdentity = 1;
    498 
    499 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
    500         const sp<Client>& client)
    501     : LayerBase(flinger, display),
    502       mHasSurface(false),
    503       mClientRef(client),
    504       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
    505 {
    506 }
    507 
    508 LayerBaseClient::~LayerBaseClient()
    509 {
    510     sp<Client> c(mClientRef.promote());
    511     if (c != 0) {
    512         c->detachLayer(this);
    513     }
    514 }
    515 
    516 sp<ISurface> LayerBaseClient::createSurface()
    517 {
    518     class BSurface : public BnSurface, public LayerCleaner {
    519         virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; }
    520     public:
    521         BSurface(const sp<SurfaceFlinger>& flinger,
    522                 const sp<LayerBaseClient>& layer)
    523             : LayerCleaner(flinger, layer) { }
    524     };
    525     sp<ISurface> sur(new BSurface(mFlinger, this));
    526     return sur;
    527 }
    528 
    529 sp<ISurface> LayerBaseClient::getSurface()
    530 {
    531     sp<ISurface> s;
    532     Mutex::Autolock _l(mLock);
    533 
    534     LOG_ALWAYS_FATAL_IF(mHasSurface,
    535             "LayerBaseClient::getSurface() has already been called");
    536 
    537     mHasSurface = true;
    538     s = createSurface();
    539     mClientSurfaceBinder = s->asBinder();
    540     return s;
    541 }
    542 
    543 wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
    544     return mClientSurfaceBinder;
    545 }
    546 
    547 wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
    548     return 0;
    549 }
    550 
    551 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
    552 {
    553     LayerBase::dump(result, buffer, SIZE);
    554 
    555     sp<Client> client(mClientRef.promote());
    556     snprintf(buffer, SIZE,
    557             "      client=%p, identity=%u\n",
    558             client.get(), getIdentity());
    559 
    560     result.append(buffer);
    561 }
    562 
    563 
    564 void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
    565 {
    566     LayerBaseClient::dump(result, scratch, size);
    567 }
    568 
    569 // ---------------------------------------------------------------------------
    570 
    571 LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
    572         const sp<LayerBaseClient>& layer)
    573     : mFlinger(flinger), mLayer(layer) {
    574 }
    575 
    576 LayerBaseClient::LayerCleaner::~LayerCleaner() {
    577     // destroy client resources
    578     mFlinger->destroySurface(mLayer);
    579 }
    580 
    581 // ---------------------------------------------------------------------------
    582 
    583 }; // namespace android
    584