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