/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "SurfaceFlinger"

#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>

#include <utils/Errors.h>
#include <utils/Log.h>

#include <GLES/gl.h>
#include <GLES/glext.h>

#include <hardware/hardware.h>

#include "clz.h"
#include "LayerBase.h"
#include "LayerBlur.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"


// We don't honor the premultiplied alpha flags, which means that
// premultiplied surface may be composed using a non-premultiplied
// equation. We do this because it may be a lot faster on some hardware
// The correct value is HONOR_PREMULTIPLIED_ALPHA = 1
#define HONOR_PREMULTIPLIED_ALPHA   0

namespace android {

// ---------------------------------------------------------------------------

const uint32_t LayerBase::typeInfo = 1;
const char* const LayerBase::typeID = "LayerBase";

const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
const char* const LayerBaseClient::typeID = "LayerBaseClient";

// ---------------------------------------------------------------------------

Vector<GLuint> LayerBase::deletedTextures; 

int32_t LayerBase::sIdentity = 0;

LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
    : dpy(display), contentDirty(false),
      mFlinger(flinger),
      mTransformed(false),
      mOrientation(0),
      mCanUseCopyBit(false),
      mTransactionFlags(0),
      mPremultipliedAlpha(true),
      mIdentity(uint32_t(android_atomic_inc(&sIdentity))),
      mInvalidate(0)
{
    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
    mFlags = hw.getFlags();
}

LayerBase::~LayerBase()
{
}

const GraphicPlane& LayerBase::graphicPlane(int dpy) const
{ 
    return mFlinger->graphicPlane(dpy);
}

GraphicPlane& LayerBase::graphicPlane(int dpy)
{
    return mFlinger->graphicPlane(dpy); 
}

void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
{
    uint32_t layerFlags = 0;
    if (flags & ISurfaceComposer::eHidden)
        layerFlags = ISurfaceComposer::eLayerHidden;

    if (flags & ISurfaceComposer::eNonPremultiplied)
        mPremultipliedAlpha = false;

    mCurrentState.z         = 0;
    mCurrentState.w         = w;
    mCurrentState.h         = h;
    mCurrentState.alpha     = 0xFF;
    mCurrentState.flags     = layerFlags;
    mCurrentState.sequence  = 0;
    mCurrentState.transform.set(0, 0);

    // drawing state & current state are identical
    mDrawingState = mCurrentState;
}

void LayerBase::commitTransaction(bool skipSize) {
    const uint32_t w = mDrawingState.w;
    const uint32_t h = mDrawingState.h;
    mDrawingState = mCurrentState;
    if (skipSize) {
        mDrawingState.w = w;
        mDrawingState.h = h;
    }
}
void LayerBase::forceVisibilityTransaction() {
    // this can be called without SurfaceFlinger.mStateLock, but if we
    // can atomically increment the sequence number, it doesn't matter.
    android_atomic_inc(&mCurrentState.sequence);
    requestTransaction();
}
bool LayerBase::requestTransaction() {
    int32_t old = setTransactionFlags(eTransactionNeeded);
    return ((old & eTransactionNeeded) == 0);
}
uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
    return android_atomic_and(~flags, &mTransactionFlags) & flags;
}
uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
    return android_atomic_or(flags, &mTransactionFlags);
}

void LayerBase::setSizeChanged(uint32_t w, uint32_t h) {
}

bool LayerBase::setPosition(int32_t x, int32_t y) {
    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
        return false;
    mCurrentState.sequence++;
    mCurrentState.transform.set(x, y);
    requestTransaction();
    return true;
}
bool LayerBase::setLayer(uint32_t z) {
    if (mCurrentState.z == z)
        return false;
    mCurrentState.sequence++;
    mCurrentState.z = z;
    requestTransaction();
    return true;
}
bool LayerBase::setSize(uint32_t w, uint32_t h) {
    if (mCurrentState.w == w && mCurrentState.h == h)
        return false;
    setSizeChanged(w, h);
    mCurrentState.w = w;
    mCurrentState.h = h;
    requestTransaction();
    return true;
}
bool LayerBase::setAlpha(uint8_t alpha) {
    if (mCurrentState.alpha == alpha)
        return false;
    mCurrentState.sequence++;
    mCurrentState.alpha = alpha;
    requestTransaction();
    return true;
}
bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
    // TODO: check the matrix has changed
    mCurrentState.sequence++;
    mCurrentState.transform.set(
            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
    requestTransaction();
    return true;
}
bool LayerBase::setTransparentRegionHint(const Region& transparent) {
    // TODO: check the region has changed
    mCurrentState.sequence++;
    mCurrentState.transparentRegion = transparent;
    requestTransaction();
    return true;
}
bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
    if (mCurrentState.flags == newFlags)
        return false;
    mCurrentState.sequence++;
    mCurrentState.flags = newFlags;
    requestTransaction();
    return true;
}

Rect LayerBase::visibleBounds() const
{
    return mTransformedBounds;
}      

void LayerBase::setVisibleRegion(const Region& visibleRegion) {
    // always called from main thread
    visibleRegionScreen = visibleRegion;
}

void LayerBase::setCoveredRegion(const Region& coveredRegion) {
    // always called from main thread
    coveredRegionScreen = coveredRegion;
}

uint32_t LayerBase::doTransaction(uint32_t flags)
{
    const Layer::State& front(drawingState());
    const Layer::State& temp(currentState());

    if (temp.sequence != front.sequence) {
        // invalidate and recompute the visible regions if needed
        flags |= eVisibleRegion;
        this->contentDirty = true;
    }
    
    // Commit the transaction
    commitTransaction(flags & eRestartTransaction);
    return flags;
}

Point LayerBase::getPhysicalSize() const
{
    const Layer::State& front(drawingState());
    return Point(front.w, front.h);
}

void LayerBase::validateVisibility(const Transform& planeTransform)
{
    const Layer::State& s(drawingState());
    const Transform tr(planeTransform * s.transform);
    const bool transformed = tr.transformed();
   
    const Point size(getPhysicalSize());
    uint32_t w = size.x;
    uint32_t h = size.y;    
    tr.transform(mVertices[0], 0, 0);
    tr.transform(mVertices[1], 0, h);
    tr.transform(mVertices[2], w, h);
    tr.transform(mVertices[3], w, 0);
    if (UNLIKELY(transformed)) {
        // NOTE: here we could also punt if we have too many rectangles
        // in the transparent region
        if (tr.preserveRects()) {
            // transform the transparent region
            transparentRegionScreen = tr.transform(s.transparentRegion);
        } else {
            // transformation too complex, can't do the transparent region
            // optimization.
            transparentRegionScreen.clear();
        }
    } else {
        transparentRegionScreen = s.transparentRegion;
    }

    // cache a few things...
    mOrientation = tr.getOrientation();
    mTransformedBounds = tr.makeBounds(w, h);
    mTransformed = transformed;
    mLeft = tr.tx();
    mTop  = tr.ty();

    // see if we can/should use 2D h/w with the new configuration
    mCanUseCopyBit = false;
    copybit_device_t* copybit = mFlinger->getBlitEngine();
    if (copybit) { 
        const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
        const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
        mCanUseCopyBit = true;
        if ((mOrientation < 0) && (step > 1)) {
            // arbitrary orientations not supported
            mCanUseCopyBit = false;
        } else if ((mOrientation > 0) && (step > 90)) {
            // 90 deg rotations not supported
            mCanUseCopyBit = false;
        } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 
            // arbitrary scaling not supported
            mCanUseCopyBit = false;
        }
#if HONOR_PREMULTIPLIED_ALPHA 
        else if (needsBlending() && mPremultipliedAlpha) {
            // pre-multiplied alpha not supported
            mCanUseCopyBit = false;
        }
#endif
        else {
            // here, we determined we can use copybit
            if (tr.getType() & SkMatrix::kScale_Mask) {
                // and we have scaling
                if (!transparentRegionScreen.isRect()) {
                    // we punt because blending is cheap (h/w) and the region is
                    // complex, which may causes artifacts when copying
                    // scaled content
                    transparentRegionScreen.clear();
                }
            }
        }
    }
}

void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
{
}

void LayerBase::unlockPageFlip(
        const Transform& planeTransform, Region& outDirtyRegion)
{
    if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
        outDirtyRegion.orSelf(visibleRegionScreen);
    }
}

void LayerBase::finishPageFlip()
{
}

void LayerBase::invalidate()
{
    if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
        mFlinger->signalEvent();
    }
}

void LayerBase::drawRegion(const Region& reg) const
{
    Region::iterator iterator(reg);
    if (iterator) {
        Rect r;
        const DisplayHardware& hw(graphicPlane(0).displayHardware());
        const int32_t fbWidth  = hw.getWidth();
        const int32_t fbHeight = hw.getHeight();
        const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 
                { fbWidth, fbHeight }, { 0, fbHeight }  };
        glVertexPointer(2, GL_SHORT, 0, vertices);
        while (iterator.iterate(&r)) {
            const GLint sy = fbHeight - (r.top + r.height());
            glScissor(r.left, sy, r.width(), r.height());
            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
        }
    }
}

void LayerBase::draw(const Region& inClip) const
{
    // invalidate the region we'll update
    Region clip(inClip);  // copy-on-write, so no-op most of the time

    // Remove the transparent area from the clipping region
    const State& s = drawingState();
    if (LIKELY(!s.transparentRegion.isEmpty())) {
        clip.subtract(transparentRegionScreen);
        if (clip.isEmpty()) {
            // usually this won't happen because this should be taken care of
            // by SurfaceFlinger::computeVisibleRegions()
            return;
        }        
    }

    // reset GL state
    glEnable(GL_SCISSOR_TEST);

    onDraw(clip);

    /*
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DITHER);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glColor4x(0, 0x8000, 0, 0x10000);
    drawRegion(transparentRegionScreen);
    glDisable(GL_BLEND);
    */
}

GLuint LayerBase::createTexture() const
{
    GLuint textureName = -1;
    glGenTextures(1, &textureName);
    glBindTexture(GL_TEXTURE_2D, textureName);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    if (mFlags & DisplayHardware::SLOW_CONFIG) {
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    } else {
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    }
    return textureName;
}

void LayerBase::clearWithOpenGL(const Region& clip) const
{
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    const uint32_t fbHeight = hw.getHeight();
    glColor4x(0,0,0,0);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glDisable(GL_DITHER);
    Rect r;
    Region::iterator iterator(clip);
    if (iterator) {
        glEnable(GL_SCISSOR_TEST);
        glVertexPointer(2, GL_FIXED, 0, mVertices);
        while (iterator.iterate(&r)) {
            const GLint sy = fbHeight - (r.top + r.height());
            glScissor(r.left, sy, r.width(), r.height());
            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
        }
    }
}

void LayerBase::drawWithOpenGL(const Region& clip,
        GLint textureName, const GGLSurface& t, int transform) const
{
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    const uint32_t fbHeight = hw.getHeight();
    const State& s(drawingState());

    // bind our texture
    validateTexture(textureName);
    glEnable(GL_TEXTURE_2D);

    // Dithering...
    if (s.flags & ISurfaceComposer::eLayerDither) {
        glEnable(GL_DITHER);
    } else {
        glDisable(GL_DITHER);
    }

    if (UNLIKELY(s.alpha < 0xFF)) {
        // We have an alpha-modulation. We need to modulate all
        // texture components by alpha because we're always using 
        // premultiplied alpha.
        
        // If the texture doesn't have an alpha channel we can
        // use REPLACE and switch to non premultiplied alpha
        // blending (SRCA/ONE_MINUS_SRCA).
        
        GLenum env, src;
        if (needsBlending()) {
            env = GL_MODULATE;
            src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
        } else {
            env = GL_REPLACE;
            src = GL_SRC_ALPHA;
        }
        const GGLfixed alpha = (s.alpha << 16)/255;
        glColor4x(alpha, alpha, alpha, alpha);
        glEnable(GL_BLEND);
        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
    } else {
        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
        if (needsBlending()) {
            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
            glEnable(GL_BLEND);
            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
        } else {
            glDisable(GL_BLEND);
        }
    }

    if (UNLIKELY(transformed()
            || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
    {
        //StopWatch watch("GL transformed");
        Region::iterator iterator(clip);
        if (iterator) {
            // always use high-quality filtering with fast configurations
            bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            }            
            const GLfixed texCoords[4][2] = {
                    { 0,        0 },
                    { 0,        0x10000 },
                    { 0x10000,  0x10000 },
                    { 0x10000,  0 }
            };

            glMatrixMode(GL_TEXTURE);
            glLoadIdentity();
            
            if (transform == HAL_TRANSFORM_ROT_90) {
                glTranslatef(0, 1, 0);
                glRotatef(-90, 0, 0, 1);
            }

            if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
                // find the smallest power-of-two that will accommodate our surface
                GLuint tw = 1 << (31 - clz(t.width));
                GLuint th = 1 << (31 - clz(t.height));
                if (tw < t.width)  tw <<= 1;
                if (th < t.height) th <<= 1;
                // this divide should be relatively fast because it's
                // a power-of-two (optimized path in libgcc)
                GLfloat ws = GLfloat(t.width) /tw;
                GLfloat hs = GLfloat(t.height)/th;
                glScalef(ws, hs, 1.0f);
            }

            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            glVertexPointer(2, GL_FIXED, 0, mVertices);
            glTexCoordPointer(2, GL_FIXED, 0, texCoords);

            Rect r;
            while (iterator.iterate(&r)) {
                const GLint sy = fbHeight - (r.top + r.height());
                glScissor(r.left, sy, r.width(), r.height());
                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
            }

            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            }
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        }
    } else {
        Region::iterator iterator(clip);
        if (iterator) {
            Rect r;
            GLint crop[4] = { 0, t.height, t.width, -t.height };
            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
            int x = tx();
            int y = ty();
            y = fbHeight - (y + t.height);
            while (iterator.iterate(&r)) {
                const GLint sy = fbHeight - (r.top + r.height());
                glScissor(r.left, sy, r.width(), r.height());
                glDrawTexiOES(x, y, 0, t.width, t.height);
            }
        }
    }
}

void LayerBase::validateTexture(GLint textureName) const
{
    glBindTexture(GL_TEXTURE_2D, textureName);
    // TODO: reload the texture if needed
    // this is currently done in loadTexture() below
}

void LayerBase::loadTexture(const Region& dirty,
        GLint textureName, const GGLSurface& t,
        GLuint& textureWidth, GLuint& textureHeight) const
{
    // TODO: defer the actual texture reload until LayerBase::validateTexture
    // is called.

    uint32_t flags = mFlags;
    glBindTexture(GL_TEXTURE_2D, textureName);

    GLuint tw = t.width;
    GLuint th = t.height;

    /*
     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
     * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of
     * stride).
     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
     * need to do something reasonable (here creating a bigger texture).
     * 
     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
     * 
     * This situation doesn't happen often, but some h/w have a limitation
     * for their framebuffer (eg: must be multiple of 8 pixels), and
     * we need to take that into account when using these buffers as
     * textures.
     *
     * This should never be a problem with POT textures
     */

    tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);

    /*
     * round to POT if needed 
     */
    
    GLuint texture_w = tw;
    GLuint texture_h = th;
    if (!(flags & DisplayHardware::NPOT_EXTENSION)) {
        // find the smallest power-of-two that will accommodate our surface
        texture_w = 1 << (31 - clz(t.width));
        texture_h = 1 << (31 - clz(t.height));
        if (texture_w < t.width)  texture_w <<= 1;
        if (texture_h < t.height) texture_h <<= 1;
        if (texture_w != tw || texture_h != th) {
            // we can't use DIRECT_TEXTURE since we changed the size
            // of the texture
            flags &= ~DisplayHardware::DIRECT_TEXTURE;
        }
    }

    if (flags & DisplayHardware::DIRECT_TEXTURE) {
        // here we're guaranteed that texture_{w|h} == t{w|h}
        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
                    GL_RGB, tw, th, 0,
                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
                    GL_RGBA, tw, th, 0,
                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
                    GL_RGBA, tw, th, 0,
                    GL_RGBA, GL_UNSIGNED_BYTE, t.data);
        } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) {
            // TODO: add GL_BGRA extension
        } else {
            // oops, we don't handle this format, try the regular path
            goto regular;
        }
        textureWidth = tw;
        textureHeight = th;
    } else {
regular:
        Rect bounds(dirty.bounds());
        GLvoid* data = 0;
        if (texture_w!=textureWidth || texture_h!=textureHeight) {
            // texture size changed, we need to create a new one

            if (!textureWidth || !textureHeight) {
                // this is the first time, load the whole texture
                if (texture_w==tw && texture_h==th) {
                    // we can do it one pass
                    data = t.data;
                } else {
                    // we have to create the texture first because it
                    // doesn't match the size of the buffer
                    bounds.set(Rect(tw, th));
                }
            }
            
            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
                glTexImage2D(GL_TEXTURE_2D, 0,
                        GL_RGB, texture_w, texture_h, 0,
                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
                glTexImage2D(GL_TEXTURE_2D, 0,
                        GL_RGBA, texture_w, texture_h, 0,
                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
                glTexImage2D(GL_TEXTURE_2D, 0,
                        GL_RGBA, texture_w, texture_h, 0,
                        GL_RGBA, GL_UNSIGNED_BYTE, data);
            } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
                        t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
                // just show the Y plane of YUV buffers
                data = t.data;
                glTexImage2D(GL_TEXTURE_2D, 0,
                        GL_LUMINANCE, texture_w, texture_h, 0,
                        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
            } else {
                // oops, we don't handle this format!
                LOGE("layer %p, texture=%d, using format %d, which is not "
                     "supported by the GL", this, textureName, t.format);
                textureName = -1;
            }
            textureWidth = texture_w;
            textureHeight = texture_h;
        }
        if (!data && textureName>=0) {
            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
                glTexSubImage2D(GL_TEXTURE_2D, 0,
                        0, bounds.top, t.width, bounds.height(),
                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
                        t.data + bounds.top*t.width*2);
            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
                glTexSubImage2D(GL_TEXTURE_2D, 0,
                        0, bounds.top, t.width, bounds.height(),
                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
                        t.data + bounds.top*t.width*2);
            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
                glTexSubImage2D(GL_TEXTURE_2D, 0,
                        0, bounds.top, t.width, bounds.height(),
                        GL_RGBA, GL_UNSIGNED_BYTE,
                        t.data + bounds.top*t.width*4);
            }
        }
    }
}

bool LayerBase::canUseCopybit() const
{
    return mCanUseCopyBit;
}

// ---------------------------------------------------------------------------

LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
        Client* c, int32_t i)
    : LayerBase(flinger, display), client(c),
      lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
      mIndex(i)
{
    if (client) {
        client->bindLayer(this, i);

        // Initialize this layer's control block
        memset(this->lcblk, 0, sizeof(layer_cblk_t));
        this->lcblk->identity = mIdentity;
        Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t));
        Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t));
    }
}

LayerBaseClient::~LayerBaseClient()
{
    if (client) {
        client->free(mIndex);
    }
}

int32_t LayerBaseClient::serverIndex() const {
    if (client) {
        return (client->cid<<16)|mIndex;
    }
    return 0xFFFF0000 | mIndex;
}

sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
{
    return new Surface(clientIndex(), mIdentity);
}


// ---------------------------------------------------------------------------

}; // namespace android
