summaryrefslogtreecommitdiffstats
path: root/libs/surfaceflinger/LayerBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/surfaceflinger/LayerBase.cpp')
-rw-r--r--libs/surfaceflinger/LayerBase.cpp740
1 files changed, 0 insertions, 740 deletions
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
deleted file mode 100644
index 0cf53f7..0000000
--- a/libs/surfaceflinger/LayerBase.cpp
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * 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