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 
     37 namespace android {
     38 
     39 // ---------------------------------------------------------------------------
     40 
     41 const uint32_t LayerBase::typeInfo = 1;
     42 const char* const LayerBase::typeID = "LayerBase";
     43 
     44 const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
     45 const char* const LayerBaseClient::typeID = "LayerBaseClient";
     46 
     47 // ---------------------------------------------------------------------------
     48 
     49 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     50     : dpy(display), contentDirty(false),
     51       mFlinger(flinger),
     52       mTransformed(false),
     53       mUseLinearFiltering(false),
     54       mOrientation(0),
     55       mLeft(0), mTop(0),
     56       mTransactionFlags(0),
     57       mPremultipliedAlpha(true), mDebug(false),
     58       mInvalidate(0)
     59 {
     60     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
     61     mFlags = hw.getFlags();
     62 }
     63 
     64 LayerBase::~LayerBase()
     65 {
     66 }
     67 
     68 void LayerBase::setName(const String8& name) {
     69     mName = name;
     70 }
     71 
     72 String8 LayerBase::getName() const {
     73     return mName;
     74 }
     75 
     76 const GraphicPlane& LayerBase::graphicPlane(int dpy) const
     77 {
     78     return mFlinger->graphicPlane(dpy);
     79 }
     80 
     81 GraphicPlane& LayerBase::graphicPlane(int dpy)
     82 {
     83     return mFlinger->graphicPlane(dpy);
     84 }
     85 
     86 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
     87 {
     88     uint32_t layerFlags = 0;
     89     if (flags & ISurfaceComposer::eHidden)
     90         layerFlags = ISurfaceComposer::eLayerHidden;
     91 
     92     if (flags & ISurfaceComposer::eNonPremultiplied)
     93         mPremultipliedAlpha = false;
     94 
     95     mCurrentState.z             = 0;
     96     mCurrentState.w             = w;
     97     mCurrentState.h             = h;
     98     mCurrentState.requested_w   = w;
     99     mCurrentState.requested_h   = h;
    100     mCurrentState.alpha         = 0xFF;
    101     mCurrentState.flags         = layerFlags;
    102     mCurrentState.sequence      = 0;
    103     mCurrentState.transform.set(0, 0);
    104 
    105     // drawing state & current state are identical
    106     mDrawingState = mCurrentState;
    107 }
    108 
    109 void LayerBase::commitTransaction() {
    110     mDrawingState = mCurrentState;
    111 }
    112 void LayerBase::forceVisibilityTransaction() {
    113     // this can be called without SurfaceFlinger.mStateLock, but if we
    114     // can atomically increment the sequence number, it doesn't matter.
    115     android_atomic_inc(&mCurrentState.sequence);
    116     requestTransaction();
    117 }
    118 bool LayerBase::requestTransaction() {
    119     int32_t old = setTransactionFlags(eTransactionNeeded);
    120     return ((old & eTransactionNeeded) == 0);
    121 }
    122 uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
    123     return android_atomic_and(~flags, &mTransactionFlags) & flags;
    124 }
    125 uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
    126     return android_atomic_or(flags, &mTransactionFlags);
    127 }
    128 
    129 bool LayerBase::setPosition(int32_t x, int32_t y) {
    130     if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
    131         return false;
    132     mCurrentState.sequence++;
    133     mCurrentState.transform.set(x, y);
    134     requestTransaction();
    135     return true;
    136 }
    137 bool LayerBase::setLayer(uint32_t z) {
    138     if (mCurrentState.z == z)
    139         return false;
    140     mCurrentState.sequence++;
    141     mCurrentState.z = z;
    142     requestTransaction();
    143     return true;
    144 }
    145 bool LayerBase::setSize(uint32_t w, uint32_t h) {
    146     if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
    147         return false;
    148     mCurrentState.requested_w = w;
    149     mCurrentState.requested_h = h;
    150     requestTransaction();
    151     return true;
    152 }
    153 bool LayerBase::setAlpha(uint8_t alpha) {
    154     if (mCurrentState.alpha == alpha)
    155         return false;
    156     mCurrentState.sequence++;
    157     mCurrentState.alpha = alpha;
    158     requestTransaction();
    159     return true;
    160 }
    161 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
    162     // TODO: check the matrix has changed
    163     mCurrentState.sequence++;
    164     mCurrentState.transform.set(
    165             matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
    166     requestTransaction();
    167     return true;
    168 }
    169 bool LayerBase::setTransparentRegionHint(const Region& transparent) {
    170     // TODO: check the region has changed
    171     mCurrentState.sequence++;
    172     mCurrentState.transparentRegion = transparent;
    173     requestTransaction();
    174     return true;
    175 }
    176 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
    177     const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
    178     if (mCurrentState.flags == newFlags)
    179         return false;
    180     mCurrentState.sequence++;
    181     mCurrentState.flags = newFlags;
    182     requestTransaction();
    183     return true;
    184 }
    185 
    186 Rect LayerBase::visibleBounds() const
    187 {
    188     return mTransformedBounds;
    189 }
    190 
    191 void LayerBase::setVisibleRegion(const Region& visibleRegion) {
    192     // always called from main thread
    193     visibleRegionScreen = visibleRegion;
    194 }
    195 
    196 void LayerBase::setCoveredRegion(const Region& coveredRegion) {
    197     // always called from main thread
    198     coveredRegionScreen = coveredRegion;
    199 }
    200 
    201 uint32_t LayerBase::doTransaction(uint32_t flags)
    202 {
    203     const Layer::State& front(drawingState());
    204     const Layer::State& temp(currentState());
    205 
    206     if ((front.requested_w != temp.requested_w) ||
    207         (front.requested_h != temp.requested_h))  {
    208         // resize the layer, set the physical size to the requested size
    209         Layer::State& editTemp(currentState());
    210         editTemp.w = temp.requested_w;
    211         editTemp.h = temp.requested_h;
    212     }
    213 
    214     if ((front.w != temp.w) || (front.h != temp.h)) {
    215         // invalidate and recompute the visible regions if needed
    216         flags |= Layer::eVisibleRegion;
    217     }
    218 
    219     if (temp.sequence != front.sequence) {
    220         // invalidate and recompute the visible regions if needed
    221         flags |= eVisibleRegion;
    222         this->contentDirty = true;
    223 
    224         const bool linearFiltering = mUseLinearFiltering;
    225         mUseLinearFiltering = false;
    226         if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
    227             // we may use linear filtering, if the matrix scales us
    228             const uint8_t type = temp.transform.getType();
    229             if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) {
    230                 mUseLinearFiltering = true;
    231             }
    232         }
    233     }
    234 
    235     // Commit the transaction
    236     commitTransaction();
    237     return flags;
    238 }
    239 
    240 void LayerBase::validateVisibility(const Transform& planeTransform)
    241 {
    242     const Layer::State& s(drawingState());
    243     const Transform tr(planeTransform * s.transform);
    244     const bool transformed = tr.transformed();
    245 
    246     uint32_t w = s.w;
    247     uint32_t h = s.h;
    248     tr.transform(mVertices[0], 0, 0);
    249     tr.transform(mVertices[1], 0, h);
    250     tr.transform(mVertices[2], w, h);
    251     tr.transform(mVertices[3], w, 0);
    252     if (UNLIKELY(transformed)) {
    253         // NOTE: here we could also punt if we have too many rectangles
    254         // in the transparent region
    255         if (tr.preserveRects()) {
    256             // transform the transparent region
    257             transparentRegionScreen = tr.transform(s.transparentRegion);
    258         } else {
    259             // transformation too complex, can't do the transparent region
    260             // optimization.
    261             transparentRegionScreen.clear();
    262         }
    263     } else {
    264         transparentRegionScreen = s.transparentRegion;
    265     }
    266 
    267     // cache a few things...
    268     mOrientation = tr.getOrientation();
    269     mTransformedBounds = tr.makeBounds(w, h);
    270     mTransformed = transformed;
    271     mLeft = tr.tx();
    272     mTop  = tr.ty();
    273 }
    274 
    275 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
    276 {
    277 }
    278 
    279 void LayerBase::unlockPageFlip(
    280         const Transform& planeTransform, Region& outDirtyRegion)
    281 {
    282     if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
    283         outDirtyRegion.orSelf(visibleRegionScreen);
    284     }
    285 }
    286 
    287 void LayerBase::finishPageFlip()
    288 {
    289 }
    290 
    291 void LayerBase::invalidate()
    292 {
    293     if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
    294         mFlinger->signalEvent();
    295     }
    296 }
    297 
    298 void LayerBase::drawRegion(const Region& reg) const
    299 {
    300     Region::const_iterator it = reg.begin();
    301     Region::const_iterator const end = reg.end();
    302     if (it != end) {
    303         Rect r;
    304         const DisplayHardware& hw(graphicPlane(0).displayHardware());
    305         const int32_t fbWidth  = hw.getWidth();
    306         const int32_t fbHeight = hw.getHeight();
    307         const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
    308                 { fbWidth, fbHeight }, { 0, fbHeight }  };
    309         glVertexPointer(2, GL_SHORT, 0, vertices);
    310         while (it != end) {
    311             const Rect& r = *it++;
    312             const GLint sy = fbHeight - (r.top + r.height());
    313             glScissor(r.left, sy, r.width(), r.height());
    314             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    315         }
    316     }
    317 }
    318 
    319 void LayerBase::draw(const Region& inClip) const
    320 {
    321     // invalidate the region we'll update
    322     Region clip(inClip);  // copy-on-write, so no-op most of the time
    323 
    324     // Remove the transparent area from the clipping region
    325     const State& s = drawingState();
    326     if (LIKELY(!s.transparentRegion.isEmpty())) {
    327         clip.subtract(transparentRegionScreen);
    328         if (clip.isEmpty()) {
    329             // usually this won't happen because this should be taken care of
    330             // by SurfaceFlinger::computeVisibleRegions()
    331             return;
    332         }
    333     }
    334 
    335     // reset GL state
    336     glEnable(GL_SCISSOR_TEST);
    337 
    338     onDraw(clip);
    339 
    340     /*
    341     glDisable(GL_TEXTURE_2D);
    342     glDisable(GL_DITHER);
    343     glEnable(GL_BLEND);
    344     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    345     glColor4x(0, 0x8000, 0, 0x10000);
    346     drawRegion(transparentRegionScreen);
    347     glDisable(GL_BLEND);
    348     */
    349 }
    350 
    351 GLuint LayerBase::createTexture() const
    352 {
    353     GLuint textureName = -1;
    354     glGenTextures(1, &textureName);
    355     glBindTexture(GL_TEXTURE_2D, textureName);
    356     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    357     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    358     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    359     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    360     return textureName;
    361 }
    362 
    363 void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red,
    364                                 GLclampx green, GLclampx blue,
    365                                 GLclampx alpha) const
    366 {
    367     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    368     const uint32_t fbHeight = hw.getHeight();
    369     glColor4x(red,green,blue,alpha);
    370     glDisable(GL_TEXTURE_2D);
    371     glDisable(GL_BLEND);
    372     glDisable(GL_DITHER);
    373 
    374     Region::const_iterator it = clip.begin();
    375     Region::const_iterator const end = clip.end();
    376     glEnable(GL_SCISSOR_TEST);
    377     glVertexPointer(2, GL_FIXED, 0, mVertices);
    378     while (it != end) {
    379         const Rect& r = *it++;
    380         const GLint sy = fbHeight - (r.top + r.height());
    381         glScissor(r.left, sy, r.width(), r.height());
    382         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    383     }
    384 }
    385 
    386 void LayerBase::clearWithOpenGL(const Region& clip) const
    387 {
    388     clearWithOpenGL(clip,0,0,0,0);
    389 }
    390 
    391 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
    392 {
    393     const DisplayHardware& hw(graphicPlane(0).displayHardware());
    394     const uint32_t fbHeight = hw.getHeight();
    395     const State& s(drawingState());
    396 
    397     // bind our texture
    398     validateTexture(texture.name);
    399     uint32_t width  = texture.width;
    400     uint32_t height = texture.height;
    401 
    402     glEnable(GL_TEXTURE_2D);
    403 
    404     if (UNLIKELY(s.alpha < 0xFF)) {
    405         // We have an alpha-modulation. We need to modulate all
    406         // texture components by alpha because we're always using
    407         // premultiplied alpha.
    408 
    409         // If the texture doesn't have an alpha channel we can
    410         // use REPLACE and switch to non premultiplied alpha
    411         // blending (SRCA/ONE_MINUS_SRCA).
    412 
    413         GLenum env, src;
    414         if (needsBlending()) {
    415             env = GL_MODULATE;
    416             src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
    417         } else {
    418             env = GL_REPLACE;
    419             src = GL_SRC_ALPHA;
    420         }
    421         const GGLfixed alpha = (s.alpha << 16)/255;
    422         glColor4x(alpha, alpha, alpha, alpha);
    423         glEnable(GL_BLEND);
    424         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
    425         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
    426     } else {
    427         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    428         glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
    429         if (needsBlending()) {
    430             GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
    431             glEnable(GL_BLEND);
    432             glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
    433         } else {
    434             glDisable(GL_BLEND);
    435         }
    436     }
    437 
    438     Region::const_iterator it = clip.begin();
    439     Region::const_iterator const end = clip.end();
    440 
    441     //StopWatch watch("GL transformed");
    442     const GLfixed texCoords[4][2] = {
    443             { 0,        0 },
    444             { 0,        0x10000 },
    445             { 0x10000,  0x10000 },
    446             { 0x10000,  0 }
    447     };
    448 
    449     glMatrixMode(GL_TEXTURE);
    450     glLoadIdentity();
    451 
    452     // the texture's source is rotated
    453     switch (texture.transform) {
    454         case HAL_TRANSFORM_ROT_90:
    455             glTranslatef(0, 1, 0);
    456             glRotatef(-90, 0, 0, 1);
    457             break;
    458         case HAL_TRANSFORM_ROT_180:
    459             glTranslatef(1, 1, 0);
    460             glRotatef(-180, 0, 0, 1);
    461             break;
    462         case HAL_TRANSFORM_ROT_270:
    463             glTranslatef(1, 0, 0);
    464             glRotatef(-270, 0, 0, 1);
    465             break;
    466     }
    467 
    468     if (texture.NPOTAdjust) {
    469         glScalef(texture.wScale, texture.hScale, 1.0f);
    470     }
    471 
    472     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    473     glVertexPointer(2, GL_FIXED, 0, mVertices);
    474     glTexCoordPointer(2, GL_FIXED, 0, texCoords);
    475 
    476     while (it != end) {
    477         const Rect& r = *it++;
    478         const GLint sy = fbHeight - (r.top + r.height());
    479         glScissor(r.left, sy, r.width(), r.height());
    480         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    481     }
    482     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    483 }
    484 
    485 void LayerBase::validateTexture(GLint textureName) const
    486 {
    487     glBindTexture(GL_TEXTURE_2D, textureName);
    488     // TODO: reload the texture if needed
    489     // this is currently done in loadTexture() below
    490     if (mUseLinearFiltering) {
    491         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    492         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    493     } else {
    494         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    495         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    496     }
    497 
    498     if (needsDithering()) {
    499         glEnable(GL_DITHER);
    500     } else {
    501         glDisable(GL_DITHER);
    502     }
    503 }
    504 
    505 bool LayerBase::isSupportedYuvFormat(int format) const
    506 {
    507     switch (format) {
    508         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    509         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    510         case HAL_PIXEL_FORMAT_YCbCr_422_P:
    511         case HAL_PIXEL_FORMAT_YCbCr_420_P:
    512         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    513         case HAL_PIXEL_FORMAT_YCbCr_420_I:
    514         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    515             return true;
    516     }
    517     return false;
    518 }
    519 
    520 void LayerBase::loadTexture(Texture* texture,
    521         const Region& dirty, const GGLSurface& t) const
    522 {
    523     if (texture->name == -1U) {
    524         // uh?
    525         return;
    526     }
    527 
    528     glBindTexture(GL_TEXTURE_2D, texture->name);
    529 
    530     /*
    531      * In OpenGL ES we can't specify a stride with glTexImage2D (however,
    532      * GL_UNPACK_ALIGNMENT is a limited form of stride).
    533      * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
    534      * need to do something reasonable (here creating a bigger texture).
    535      *
    536      * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
    537      *
    538      * This situation doesn't happen often, but some h/w have a limitation
    539      * for their framebuffer (eg: must be multiple of 8 pixels), and
    540      * we need to take that into account when using these buffers as
    541      * textures.
    542      *
    543      * This should never be a problem with POT textures
    544      */
    545 
    546     int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
    547     unpack = 1 << ((unpack > 3) ? 3 : unpack);
    548     glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
    549 
    550     /*
    551      * round to POT if needed
    552      */
    553     if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
    554         texture->NPOTAdjust = true;
    555     }
    556 
    557     if (texture->NPOTAdjust) {
    558         // find the smallest power-of-two that will accommodate our surface
    559         texture->potWidth  = 1 << (31 - clz(t.width));
    560         texture->potHeight = 1 << (31 - clz(t.height));
    561         if (texture->potWidth  < t.width)  texture->potWidth  <<= 1;
    562         if (texture->potHeight < t.height) texture->potHeight <<= 1;
    563         texture->wScale = float(t.width)  / texture->potWidth;
    564         texture->hScale = float(t.height) / texture->potHeight;
    565     } else {
    566         texture->potWidth  = t.width;
    567         texture->potHeight = t.height;
    568     }
    569 
    570     Rect bounds(dirty.bounds());
    571     GLvoid* data = 0;
    572     if (texture->width != t.width || texture->height != t.height) {
    573         texture->width  = t.width;
    574         texture->height = t.height;
    575 
    576         // texture size changed, we need to create a new one
    577         bounds.set(Rect(t.width, t.height));
    578         if (t.width  == texture->potWidth &&
    579             t.height == texture->potHeight) {
    580             // we can do it one pass
    581             data = t.data;
    582         }
    583 
    584         if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
    585             glTexImage2D(GL_TEXTURE_2D, 0,
    586                     GL_RGB, texture->potWidth, texture->potHeight, 0,
    587                     GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
    588         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
    589             glTexImage2D(GL_TEXTURE_2D, 0,
    590                     GL_RGBA, texture->potWidth, texture->potHeight, 0,
    591                     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
    592         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
    593                    t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
    594             glTexImage2D(GL_TEXTURE_2D, 0,
    595                     GL_RGBA, texture->potWidth, texture->potHeight, 0,
    596                     GL_RGBA, GL_UNSIGNED_BYTE, data);
    597         } else if (isSupportedYuvFormat(t.format)) {
    598             // just show the Y plane of YUV buffers
    599             glTexImage2D(GL_TEXTURE_2D, 0,
    600                     GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
    601                     GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
    602         } else {
    603             // oops, we don't handle this format!
    604             LOGE("layer %p, texture=%d, using format %d, which is not "
    605                  "supported by the GL", this, texture->name, t.format);
    606         }
    607     }
    608     if (!data) {
    609         if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
    610             glTexSubImage2D(GL_TEXTURE_2D, 0,
    611                     0, bounds.top, t.width, bounds.height(),
    612                     GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
    613                     t.data + bounds.top*t.stride*2);
    614         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
    615             glTexSubImage2D(GL_TEXTURE_2D, 0,
    616                     0, bounds.top, t.width, bounds.height(),
    617                     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
    618                     t.data + bounds.top*t.stride*2);
    619         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
    620                    t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
    621             glTexSubImage2D(GL_TEXTURE_2D, 0,
    622                     0, bounds.top, t.width, bounds.height(),
    623                     GL_RGBA, GL_UNSIGNED_BYTE,
    624                     t.data + bounds.top*t.stride*4);
    625         } else if (isSupportedYuvFormat(t.format)) {
    626             // just show the Y plane of YUV buffers
    627             glTexSubImage2D(GL_TEXTURE_2D, 0,
    628                     0, bounds.top, t.width, bounds.height(),
    629                     GL_LUMINANCE, GL_UNSIGNED_BYTE,
    630                     t.data + bounds.top*t.stride);
    631         }
    632     }
    633 }
    634 
    635 status_t LayerBase::initializeEglImage(
    636         const sp<GraphicBuffer>& buffer, Texture* texture)
    637 {
    638     status_t err = NO_ERROR;
    639 
    640     // we need to recreate the texture
    641     EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
    642 
    643     // free the previous image
    644     if (texture->image != EGL_NO_IMAGE_KHR) {
    645         eglDestroyImageKHR(dpy, texture->image);
    646         texture->image = EGL_NO_IMAGE_KHR;
    647     }
    648 
    649     // construct an EGL_NATIVE_BUFFER_ANDROID
    650     android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
    651 
    652     // create the new EGLImageKHR
    653     const EGLint attrs[] = {
    654             EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
    655             EGL_NONE,                   EGL_NONE
    656     };
    657     texture->image = eglCreateImageKHR(
    658             dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
    659             (EGLClientBuffer)clientBuf, attrs);
    660 
    661     if (texture->image != EGL_NO_IMAGE_KHR) {
    662         glBindTexture(GL_TEXTURE_2D, texture->name);
    663         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
    664                 (GLeglImageOES)texture->image);
    665         GLint error = glGetError();
    666         if (UNLIKELY(error != GL_NO_ERROR)) {
    667             LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
    668                  "failed err=0x%04x",
    669                  this, texture->image, error);
    670             err = INVALID_OPERATION;
    671         } else {
    672             // Everything went okay!
    673             texture->NPOTAdjust = false;
    674             texture->dirty  = false;
    675             texture->width  = clientBuf->width;
    676             texture->height = clientBuf->height;
    677         }
    678     } else {
    679         LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x",
    680                 this, eglGetError());
    681         err = INVALID_OPERATION;
    682     }
    683     return err;
    684 }
    685 
    686 
    687 // ---------------------------------------------------------------------------
    688 
    689 int32_t LayerBaseClient::sIdentity = 0;
    690 
    691 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
    692         const sp<Client>& client, int32_t i)
    693     : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
    694       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
    695 {
    696     lcblk = new SharedBufferServer(
    697             client->ctrlblk, i, NUM_BUFFERS,
    698             mIdentity);
    699 }
    700 
    701 void LayerBaseClient::onFirstRef()
    702 {
    703     sp<Client> client(this->client.promote());
    704     if (client != 0) {
    705         client->bindLayer(this, mIndex);
    706     }
    707 }
    708 
    709 LayerBaseClient::~LayerBaseClient()
    710 {
    711     sp<Client> client(this->client.promote());
    712     if (client != 0) {
    713         client->free(mIndex);
    714     }
    715     delete lcblk;
    716 }
    717 
    718 int32_t LayerBaseClient::serverIndex() const
    719 {
    720     sp<Client> client(this->client.promote());
    721     if (client != 0) {
    722         return (client->cid<<16)|mIndex;
    723     }
    724     return 0xFFFF0000 | mIndex;
    725 }
    726 
    727 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
    728 {
    729     sp<Surface> s;
    730     Mutex::Autolock _l(mLock);
    731     s = mClientSurface.promote();
    732     if (s == 0) {
    733         s = createSurface();
    734         mClientSurface = s;
    735     }
    736     return s;
    737 }
    738 
    739 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
    740 {
    741     return new Surface(mFlinger, clientIndex(), mIdentity,
    742             const_cast<LayerBaseClient *>(this));
    743 }
    744 
    745 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
    746 // in the purgatory list
    747 void LayerBaseClient::onRemoved()
    748 {
    749     // wake up the condition
    750     lcblk->setStatus(NO_INIT);
    751 }
    752 
    753 // ---------------------------------------------------------------------------
    754 
    755 LayerBaseClient::Surface::Surface(
    756         const sp<SurfaceFlinger>& flinger,
    757         SurfaceID id, int identity,
    758         const sp<LayerBaseClient>& owner)
    759     : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner)
    760 {
    761 }
    762 
    763 LayerBaseClient::Surface::~Surface()
    764 {
    765     /*
    766      * This is a good place to clean-up all client resources
    767      */
    768 
    769     // destroy client resources
    770     sp<LayerBaseClient> layer = getOwner();
    771     if (layer != 0) {
    772         mFlinger->destroySurface(layer);
    773     }
    774 }
    775 
    776 sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
    777     sp<LayerBaseClient> owner(mOwner.promote());
    778     return owner;
    779 }
    780 
    781 status_t LayerBaseClient::Surface::onTransact(
    782         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    783 {
    784     switch (code) {
    785         case REGISTER_BUFFERS:
    786         case UNREGISTER_BUFFERS:
    787         case CREATE_OVERLAY:
    788         {
    789             if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
    790                 IPCThreadState* ipc = IPCThreadState::self();
    791                 const int pid = ipc->getCallingPid();
    792                 const int uid = ipc->getCallingUid();
    793                 LOGE("Permission Denial: "
    794                         "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
    795                 return PERMISSION_DENIED;
    796             }
    797         }
    798     }
    799     return BnSurface::onTransact(code, data, reply, flags);
    800 }
    801 
    802 sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage)
    803 {
    804     return NULL;
    805 }
    806 
    807 status_t LayerBaseClient::Surface::registerBuffers(
    808         const ISurface::BufferHeap& buffers)
    809 {
    810     return INVALID_OPERATION;
    811 }
    812 
    813 void LayerBaseClient::Surface::postBuffer(ssize_t offset)
    814 {
    815 }
    816 
    817 void LayerBaseClient::Surface::unregisterBuffers()
    818 {
    819 }
    820 
    821 sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
    822         uint32_t w, uint32_t h, int32_t format, int32_t orientation)
    823 {
    824     return NULL;
    825 };
    826 
    827 // ---------------------------------------------------------------------------
    828 
    829 }; // namespace android
    830