diff options
Diffstat (limited to 'libs/surfaceflinger')
36 files changed, 0 insertions, 8940 deletions
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk deleted file mode 100644 index a14bfb5..0000000 --- a/libs/surfaceflinger/Android.mk +++ /dev/null @@ -1,52 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - clz.cpp.arm \ - DisplayHardware/DisplayHardware.cpp \ - DisplayHardware/DisplayHardwareBase.cpp \ - BlurFilter.cpp.arm \ - GLExtensions.cpp \ - Layer.cpp \ - LayerBase.cpp \ - LayerBuffer.cpp \ - LayerBlur.cpp \ - LayerDim.cpp \ - MessageQueue.cpp \ - SurfaceFlinger.cpp \ - TextureManager.cpp \ - Transform.cpp - -LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" -LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES - -ifeq ($(TARGET_BOARD_PLATFORM), omap3) - LOCAL_CFLAGS += -DNO_RGBX_8888 -endif - -# need "-lrt" on Linux simulator to pick up clock_gettime -ifeq ($(TARGET_SIMULATOR),true) - ifeq ($(HOST_OS),linux) - LOCAL_LDLIBS += -lrt -lpthread - endif -endif - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libpixelflinger \ - libhardware \ - libutils \ - libEGL \ - libGLESv1_CM \ - libbinder \ - libui \ - libsurfaceflinger_client - -LOCAL_C_INCLUDES := \ - $(call include-path-for, corecg graphics) - -LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc - -LOCAL_MODULE:= libsurfaceflinger - -include $(BUILD_SHARED_LIBRARY) diff --git a/libs/surfaceflinger/Barrier.h b/libs/surfaceflinger/Barrier.h deleted file mode 100644 index 6f8507e..0000000 --- a/libs/surfaceflinger/Barrier.h +++ /dev/null @@ -1,55 +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. - */ - -#ifndef ANDROID_BARRIER_H -#define ANDROID_BARRIER_H - -#include <stdint.h> -#include <sys/types.h> -#include <utils/threads.h> - -namespace android { - -class Barrier -{ -public: - inline Barrier() : state(CLOSED) { } - inline ~Barrier() { } - void open() { - Mutex::Autolock _l(lock); - state = OPENED; - cv.broadcast(); - } - void close() { - Mutex::Autolock _l(lock); - state = CLOSED; - } - void wait() const { - Mutex::Autolock _l(lock); - while (state == CLOSED) { - cv.wait(lock); - } - } -private: - enum { OPENED, CLOSED }; - mutable Mutex lock; - mutable Condition cv; - volatile int state; -}; - -}; // namespace android - -#endif // ANDROID_BARRIER_H diff --git a/libs/surfaceflinger/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp deleted file mode 100644 index 1ffbd5b..0000000 --- a/libs/surfaceflinger/BlurFilter.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* -** -** Copyright 2006, 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. -*/ - - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <utils/Errors.h> - -#include <pixelflinger/pixelflinger.h> - -#include "clz.h" - -#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) -#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) - -namespace android { - -#if BYTE_ORDER == LITTLE_ENDIAN -inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) { - return v; -} -inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) { - return v; -} -#else -inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) { - return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00); -} -inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) { - return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00); -} -#endif - -const int BLUR_DITHER_BITS = 6; // dither weights stored on 6 bits -const int BLUR_DITHER_ORDER_SHIFT= 3; -const int BLUR_DITHER_ORDER = (1<<BLUR_DITHER_ORDER_SHIFT); -const int BLUR_DITHER_SIZE = BLUR_DITHER_ORDER * BLUR_DITHER_ORDER; -const int BLUR_DITHER_MASK = BLUR_DITHER_ORDER-1; - -static const uint8_t gDitherMatrix[BLUR_DITHER_SIZE] = { - 0, 32, 8, 40, 2, 34, 10, 42, - 48, 16, 56, 24, 50, 18, 58, 26, - 12, 44, 4, 36, 14, 46, 6, 38, - 60, 28, 52, 20, 62, 30, 54, 22, - 3, 35, 11, 43, 1, 33, 9, 41, - 51, 19, 59, 27, 49, 17, 57, 25, - 15, 47, 7, 39, 13, 45, 5, 37, - 63, 31, 55, 23, 61, 29, 53, 21 -}; - - -template <int FACTOR = 0> -struct BlurColor565 -{ - typedef uint16_t type; - int r, g, b; - inline BlurColor565() { } - inline BlurColor565(uint16_t v) { - r = v >> 11; - g = (v >> 5) & 0x3E; - b = v & 0x1F; - } - inline void clear() { r=g=b=0; } - inline uint16_t to(int shift, int last, int dither) const { - int R = r; - int G = g; - int B = b; - if (UNLIKELY(last)) { - if (FACTOR>0) { - int L = (R+G+B)>>1; - R += (((L>>1) - R) * FACTOR) >> 8; - G += (((L ) - G) * FACTOR) >> 8; - B += (((L>>1) - B) * FACTOR) >> 8; - } - R += (dither << shift) >> BLUR_DITHER_BITS; - G += (dither << shift) >> BLUR_DITHER_BITS; - B += (dither << shift) >> BLUR_DITHER_BITS; - } - R >>= shift; - G >>= shift; - B >>= shift; - return (R<<11) | (G<<5) | B; - } - inline BlurColor565& operator += (const BlurColor565& rhs) { - r += rhs.r; - g += rhs.g; - b += rhs.b; - return *this; - } - inline BlurColor565& operator -= (const BlurColor565& rhs) { - r -= rhs.r; - g -= rhs.g; - b -= rhs.b; - return *this; - } -}; - -template <int FACTOR = 0> -struct BlurColor888X -{ - typedef uint32_t type; - int r, g, b; - inline BlurColor888X() { } - inline BlurColor888X(uint32_t v) { - v = BLUR_RGBA_TO_HOST(v); - r = v & 0xFF; - g = (v >> 8) & 0xFF; - b = (v >> 16) & 0xFF; - } - inline void clear() { r=g=b=0; } - inline uint32_t to(int shift, int last, int dither) const { - int R = r; - int G = g; - int B = b; - if (UNLIKELY(last)) { - if (FACTOR>0) { - int L = (R+G+G+B)>>2; - R += ((L - R) * FACTOR) >> 8; - G += ((L - G) * FACTOR) >> 8; - B += ((L - B) * FACTOR) >> 8; - } - } - R >>= shift; - G >>= shift; - B >>= shift; - return BLUR_HOST_TO_RGBA((0xFF<<24) | (B<<16) | (G<<8) | R); - } - inline BlurColor888X& operator += (const BlurColor888X& rhs) { - r += rhs.r; - g += rhs.g; - b += rhs.b; - return *this; - } - inline BlurColor888X& operator -= (const BlurColor888X& rhs) { - r -= rhs.r; - g -= rhs.g; - b -= rhs.b; - return *this; - } -}; - -struct BlurGray565 -{ - typedef uint16_t type; - int l; - inline BlurGray565() { } - inline BlurGray565(uint16_t v) { - int r = v >> 11; - int g = (v >> 5) & 0x3F; - int b = v & 0x1F; - l = (r + g + b + 1)>>1; - } - inline void clear() { l=0; } - inline uint16_t to(int shift, int last, int dither) const { - int L = l; - if (UNLIKELY(last)) { - L += (dither << shift) >> BLUR_DITHER_BITS; - } - L >>= shift; - return ((L>>1)<<11) | (L<<5) | (L>>1); - } - inline BlurGray565& operator += (const BlurGray565& rhs) { - l += rhs.l; - return *this; - } - inline BlurGray565& operator -= (const BlurGray565& rhs) { - l -= rhs.l; - return *this; - } -}; - -struct BlurGray8888 -{ - typedef uint32_t type; - int l, a; - inline BlurGray8888() { } - inline BlurGray8888(uint32_t v) { - v = BLUR_RGBA_TO_HOST(v); - int r = v & 0xFF; - int g = (v >> 8) & 0xFF; - int b = (v >> 16) & 0xFF; - a = v >> 24; - l = r + g + g + b; - } - inline void clear() { l=a=0; } - inline uint32_t to(int shift, int last, int dither) const { - int L = l; - int A = a; - if (UNLIKELY(last)) { - L += (dither << (shift+2)) >> BLUR_DITHER_BITS; - A += (dither << shift) >> BLUR_DITHER_BITS; - } - L >>= (shift+2); - A >>= shift; - return BLUR_HOST_TO_RGBA((A<<24) | (L<<16) | (L<<8) | L); - } - inline BlurGray8888& operator += (const BlurGray8888& rhs) { - l += rhs.l; - a += rhs.a; - return *this; - } - inline BlurGray8888& operator -= (const BlurGray8888& rhs) { - l -= rhs.l; - a -= rhs.a; - return *this; - } -}; - - -template<typename PIXEL> -static status_t blurFilter( - GGLSurface const* dst, - GGLSurface const* src, - int kernelSizeUser, - int repeat) -{ - typedef typename PIXEL::type TYPE; - - const int shift = 31 - clz(kernelSizeUser); - const int areaShift = shift*2; - const int kernelSize = 1<<shift; - const int kernelHalfSize = kernelSize/2; - const int mask = kernelSize-1; - const int w = src->width; - const int h = src->height; - const uint8_t* ditherMatrix = gDitherMatrix; - - // we need a temporary buffer to store one line of blurred columns - // as well as kernelSize lines of source pixels organized as a ring buffer. - void* const temporary_buffer = malloc( - (w + kernelSize) * sizeof(PIXEL) + - (src->stride * kernelSize) * sizeof(TYPE)); - if (!temporary_buffer) - return NO_MEMORY; - - PIXEL* const sums = (PIXEL*)temporary_buffer; - TYPE* const scratch = (TYPE*)(sums + w + kernelSize); - - // Apply the blur 'repeat' times, this is used to approximate - // gaussian blurs. 3 times gives good results. - for (int k=0 ; k<repeat ; k++) { - - // Clear the columns sums for this round - memset(sums, 0, (w + kernelSize) * sizeof(PIXEL)); - TYPE* head; - TYPE pixel; - PIXEL current; - - // Since we're going to override the source data we need - // to copy it in a temporary buffer. Only kernelSize lines are - // required. But since we start in the center of the kernel, - // we only copy half of the data, and fill the rest with zeros - // (assuming black/transparent pixels). - memcpy( scratch + src->stride*kernelHalfSize, - src->data, - src->stride*kernelHalfSize*sizeof(TYPE)); - - // sum half of each column, because we assume the first half is - // zeros (black/transparent). - for (int y=0 ; y<kernelHalfSize ; y++) { - head = (TYPE*)src->data + y*src->stride; - for (int x=0 ; x<w ; x++) - sums[x] += PIXEL( *head++ ); - } - - for (int y=0 ; y<h ; y++) { - TYPE* fb = (TYPE*)dst->data + y*dst->stride; - - // compute the dither matrix line - uint8_t const * ditherY = ditherMatrix - + (y & BLUR_DITHER_MASK)*BLUR_DITHER_ORDER; - - // Horizontal blur pass on the columns sums - int count, dither, x=0; - PIXEL const * out= sums; - PIXEL const * in = sums; - current.clear(); - - count = kernelHalfSize; - do { - current += *in; - in++; - } while (--count); - - count = kernelHalfSize; - do { - current += *in; - dither = *(ditherY + ((x++)&BLUR_DITHER_MASK)); - *fb++ = current.to(areaShift, k==repeat-1, dither); - in++; - } while (--count); - - count = w-kernelSize; - do { - current += *in; - current -= *out; - dither = *(ditherY + ((x++)&BLUR_DITHER_MASK)); - *fb++ = current.to(areaShift, k==repeat-1, dither); - in++, out++; - } while (--count); - - count = kernelHalfSize; - do { - current -= *out; - dither = *(ditherY + ((x++)&BLUR_DITHER_MASK)); - *fb++ = current.to(areaShift, k==repeat-1, dither); - out++; - } while (--count); - - // vertical blur pass, subtract the oldest line from each columns - // and add a new line. Subtract or add zeros at the top - // and bottom edges. - TYPE* const tail = scratch + (y & mask) * src->stride; - if (y >= kernelHalfSize) { - for (int x=0 ; x<w ; x++) - sums[x] -= PIXEL( tail[x] ); - } - if (y < h-kernelSize) { - memcpy( tail, - (TYPE*)src->data + (y+kernelHalfSize)*src->stride, - src->stride*sizeof(TYPE)); - for (int x=0 ; x<w ; x++) - sums[x] += PIXEL( tail[x] ); - } - } - - // The subsequent passes are always done in-place. - src = dst; - } - - free(temporary_buffer); - - return NO_ERROR; -} - -template status_t blurFilter< BlurColor565<0x80> >( - GGLSurface const* dst, - GGLSurface const* src, - int kernelSizeUser, - int repeat); - -status_t blurFilter( - GGLSurface const* image, - int kernelSizeUser, - int repeat) -{ - status_t err = BAD_VALUE; - if (image->format == GGL_PIXEL_FORMAT_RGB_565) { - err = blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat); - } else if (image->format == GGL_PIXEL_FORMAT_RGBX_8888) { - err = blurFilter< BlurColor888X<0x80> >(image, image, kernelSizeUser, repeat); - } - return err; -} - -} // namespace android - -//err = blur< BlurColor565<0x80> >(dst, src, kernelSizeUser, repeat); -//err = blur<BlurGray565>(dst, src, kernelSizeUser, repeat); -//err = blur<BlurGray8888>(dst, src, kernelSizeUser, repeat); diff --git a/libs/surfaceflinger/BlurFilter.h b/libs/surfaceflinger/BlurFilter.h deleted file mode 100644 index 294db43..0000000 --- a/libs/surfaceflinger/BlurFilter.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -** -** Copyright 2006, 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. -*/ - -#ifndef ANDROID_BLUR_FILTER_H -#define ANDROID_BLUR_FILTER_H - -#include <stdint.h> -#include <utils/Errors.h> - -#include <pixelflinger/pixelflinger.h> - -namespace android { - -status_t blurFilter( - GGLSurface const* image, - int kernelSizeUser, - int repeat); - -} // namespace android - -#endif // ANDROID_BLUR_FILTER_H diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp deleted file mode 100644 index 2eac0a8..0000000 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ /dev/null @@ -1,336 +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. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <math.h> - -#include <cutils/properties.h> - -#include <utils/RefBase.h> -#include <utils/Log.h> - -#include <ui/PixelFormat.h> -#include <ui/FramebufferNativeWindow.h> -#include <ui/EGLUtils.h> - -#include <GLES/gl.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include <pixelflinger/pixelflinger.h> - -#include "DisplayHardware/DisplayHardware.h" - -#include <hardware/copybit.h> -#include <hardware/overlay.h> -#include <hardware/gralloc.h> - -#include "GLExtensions.h" - -using namespace android; - - -static __attribute__((noinline)) -void checkGLErrors() -{ - do { - // there could be more than one error flag - GLenum error = glGetError(); - if (error == GL_NO_ERROR) - break; - LOGE("GL error 0x%04x", int(error)); - } while(true); -} - -static __attribute__((noinline)) -void checkEGLErrors(const char* token) -{ - EGLint error = eglGetError(); - if (error && error != EGL_SUCCESS) { - LOGE("%s: EGL error 0x%04x (%s)", - token, int(error), EGLUtils::strerror(error)); - } -} - -/* - * Initialize the display to the specified values. - * - */ - -DisplayHardware::DisplayHardware( - const sp<SurfaceFlinger>& flinger, - uint32_t dpy) - : DisplayHardwareBase(flinger, dpy), - mFlags(0) -{ - init(dpy); -} - -DisplayHardware::~DisplayHardware() -{ - fini(); -} - -float DisplayHardware::getDpiX() const { return mDpiX; } -float DisplayHardware::getDpiY() const { return mDpiY; } -float DisplayHardware::getDensity() const { return mDensity; } -float DisplayHardware::getRefreshRate() const { return mRefreshRate; } -int DisplayHardware::getWidth() const { return mWidth; } -int DisplayHardware::getHeight() const { return mHeight; } -PixelFormat DisplayHardware::getFormat() const { return mFormat; } -uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; } -uint32_t DisplayHardware::getMaxViewportDims() const { return mMaxViewportDims; } - -void DisplayHardware::init(uint32_t dpy) -{ - mNativeWindow = new FramebufferNativeWindow(); - framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); - mDpiX = mNativeWindow->xdpi; - mDpiY = mNativeWindow->ydpi; - mRefreshRate = fbDev->fps; - - mOverlayEngine = NULL; - hw_module_t const* module; - if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) { - overlay_control_open(module, &mOverlayEngine); - } - - EGLint w, h, dummy; - EGLint numConfigs=0; - EGLSurface surface; - EGLContext context; - - // initialize EGL - EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_NONE, 0, - EGL_NONE - }; - - // debug: disable h/w rendering - char property[PROPERTY_VALUE_MAX]; - if (property_get("debug.sf.hw", property, NULL) > 0) { - if (atoi(property) == 0) { - LOGW("H/W composition disabled"); - attribs[2] = EGL_CONFIG_CAVEAT; - attribs[3] = EGL_SLOW_CONFIG; - } - } - - // TODO: all the extensions below should be queried through - // eglGetProcAddress(). - - EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - eglInitialize(display, NULL, NULL); - eglGetConfigs(display, NULL, 0, &numConfigs); - - EGLConfig config; - status_t err = EGLUtils::selectConfigForNativeWindow( - display, attribs, mNativeWindow.get(), &config); - LOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); - - EGLint r,g,b,a; - eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r); - eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g); - eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b); - eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a); - - if (mNativeWindow->isUpdateOnDemand()) { - mFlags |= PARTIAL_UPDATES; - } - - if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { - if (dummy == EGL_SLOW_CONFIG) - mFlags |= SLOW_CONFIG; - } - - /* - * Create our main surface - */ - - surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); - eglQuerySurface(display, surface, EGL_WIDTH, &mWidth); - eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight); - - if (mFlags & PARTIAL_UPDATES) { - // if we have partial updates, we definitely don't need to - // preserve the backbuffer, which may be costly. - eglSurfaceAttrib(display, surface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); - } - - if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) { - if (dummy == EGL_BUFFER_PRESERVED) { - mFlags |= BUFFER_PRESERVED; - } - } - - /* Read density from build-specific ro.sf.lcd_density property - * except if it is overridden by qemu.sf.lcd_density. - */ - if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) { - if (property_get("ro.sf.lcd_density", property, NULL) <= 0) { - LOGW("ro.sf.lcd_density not defined, using 160 dpi by default."); - strcpy(property, "160"); - } - } else { - /* for the emulator case, reset the dpi values too */ - mDpiX = mDpiY = atoi(property); - } - mDensity = atoi(property) * (1.0f/160.0f); - - - /* - * Create our OpenGL ES context - */ - - context = eglCreateContext(display, config, NULL, NULL); - - mDisplay = display; - mConfig = config; - mSurface = surface; - mContext = context; - mFormat = fbDev->format; - mPageFlipCount = 0; - - /* - * Gather OpenGL ES extensions - */ - - eglMakeCurrent(display, surface, surface, context); - - GLExtensions& extensions(GLExtensions::getInstance()); - extensions.initWithGLStrings( - glGetString(GL_VENDOR), - glGetString(GL_RENDERER), - glGetString(GL_VERSION), - glGetString(GL_EXTENSIONS), - eglQueryString(display, EGL_VENDOR), - eglQueryString(display, EGL_VERSION), - eglQueryString(display, EGL_EXTENSIONS)); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); - glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims); - - -#ifdef EGL_ANDROID_swap_rectangle - if (extensions.hasExtension("EGL_ANDROID_swap_rectangle")) { - if (eglSetSwapRectangleANDROID(display, surface, - 0, 0, mWidth, mHeight) == EGL_TRUE) { - // This could fail if this extension is not supported by this - // specific surface (of config) - mFlags |= SWAP_RECTANGLE; - } - } - // when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE - // choose PARTIAL_UPDATES, which should be more efficient - if (mFlags & PARTIAL_UPDATES) - mFlags &= ~SWAP_RECTANGLE; -#endif - - LOGI("EGL informations:"); - LOGI("# of configs : %d", numConfigs); - LOGI("vendor : %s", extensions.getEglVendor()); - LOGI("version : %s", extensions.getEglVersion()); - LOGI("extensions: %s", extensions.getEglExtension()); - LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); - LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config); - - LOGI("OpenGL informations:"); - LOGI("vendor : %s", extensions.getVendor()); - LOGI("renderer : %s", extensions.getRenderer()); - LOGI("version : %s", extensions.getVersion()); - LOGI("extensions: %s", extensions.getExtension()); - LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); - LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims); - LOGI("flags = %08x", mFlags); - - // Unbind the context from this thread - eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -/* - * Clean up. Throw out our local state. - * - * (It's entirely possible we'll never get here, since this is meant - * for real hardware, which doesn't restart.) - */ - -void DisplayHardware::fini() -{ - eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglTerminate(mDisplay); - overlay_control_close(mOverlayEngine); -} - -void DisplayHardware::releaseScreen() const -{ - DisplayHardwareBase::releaseScreen(); -} - -void DisplayHardware::acquireScreen() const -{ - DisplayHardwareBase::acquireScreen(); -} - -uint32_t DisplayHardware::getPageFlipCount() const { - return mPageFlipCount; -} - -status_t DisplayHardware::compositionComplete() const { - return mNativeWindow->compositionComplete(); -} - -void DisplayHardware::flip(const Region& dirty) const -{ - checkGLErrors(); - - EGLDisplay dpy = mDisplay; - EGLSurface surface = mSurface; - -#ifdef EGL_ANDROID_swap_rectangle - if (mFlags & SWAP_RECTANGLE) { - const Region newDirty(dirty.intersect(bounds())); - const Rect b(newDirty.getBounds()); - eglSetSwapRectangleANDROID(dpy, surface, - b.left, b.top, b.width(), b.height()); - } -#endif - - if (mFlags & PARTIAL_UPDATES) { - mNativeWindow->setUpdateRectangle(dirty.getBounds()); - } - - mPageFlipCount++; - eglSwapBuffers(dpy, surface); - checkEGLErrors("eglSwapBuffers"); - - // for debugging - //glClearColor(1,0,0,0); - //glClear(GL_COLOR_BUFFER_BIT); -} - -uint32_t DisplayHardware::getFlags() const -{ - return mFlags; -} - -void DisplayHardware::makeCurrent() const -{ - eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); -} diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h deleted file mode 100644 index 66bf521..0000000 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ /dev/null @@ -1,116 +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. - */ - -#ifndef ANDROID_DISPLAY_HARDWARE_H -#define ANDROID_DISPLAY_HARDWARE_H - -#include <stdlib.h> - -#include <ui/PixelFormat.h> -#include <ui/Region.h> - -#include <GLES/gl.h> -#include <GLES/glext.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include <pixelflinger/pixelflinger.h> - -#include "GLExtensions.h" - -#include "DisplayHardware/DisplayHardwareBase.h" - -struct overlay_control_device_t; -struct framebuffer_device_t; -struct copybit_image_t; - -namespace android { - -class FramebufferNativeWindow; - -class DisplayHardware : public DisplayHardwareBase -{ -public: - enum { - COPY_BITS_EXTENSION = 0x00000008, - BUFFER_PRESERVED = 0x00010000, - PARTIAL_UPDATES = 0x00020000, // video driver feature - SLOW_CONFIG = 0x00040000, // software - SWAP_RECTANGLE = 0x00080000, - }; - - DisplayHardware( - const sp<SurfaceFlinger>& flinger, - uint32_t displayIndex); - - ~DisplayHardware(); - - void releaseScreen() const; - void acquireScreen() const; - - // Flip the front and back buffers if the back buffer is "dirty". Might - // be instantaneous, might involve copying the frame buffer around. - void flip(const Region& dirty) const; - - float getDpiX() const; - float getDpiY() const; - float getRefreshRate() const; - float getDensity() const; - int getWidth() const; - int getHeight() const; - PixelFormat getFormat() const; - uint32_t getFlags() const; - void makeCurrent() const; - uint32_t getMaxTextureSize() const; - uint32_t getMaxViewportDims() const; - - uint32_t getPageFlipCount() const; - EGLDisplay getEGLDisplay() const { return mDisplay; } - overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; } - - status_t compositionComplete() const; - - Rect bounds() const { - return Rect(mWidth, mHeight); - } - -private: - void init(uint32_t displayIndex) __attribute__((noinline)); - void fini() __attribute__((noinline)); - - EGLDisplay mDisplay; - EGLSurface mSurface; - EGLContext mContext; - EGLConfig mConfig; - float mDpiX; - float mDpiY; - float mRefreshRate; - float mDensity; - int mWidth; - int mHeight; - PixelFormat mFormat; - uint32_t mFlags; - mutable uint32_t mPageFlipCount; - GLint mMaxViewportDims; - GLint mMaxTextureSize; - - sp<FramebufferNativeWindow> mNativeWindow; - overlay_control_device_t* mOverlayEngine; -}; - -}; // namespace android - -#endif // ANDROID_DISPLAY_HARDWARE_H diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp deleted file mode 100644 index 1d09f84..0000000 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +++ /dev/null @@ -1,401 +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. - */ - -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <termios.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/resource.h> - -#include <linux/unistd.h> - -#include <utils/Log.h> - -#include "DisplayHardware/DisplayHardwareBase.h" -#include "SurfaceFlinger.h" - -// ---------------------------------------------------------------------------- -// the sim build doesn't have gettid - -#ifndef HAVE_GETTID -# define gettid getpid -#endif - -// ---------------------------------------------------------------------------- -namespace android { - -static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep"; -static char const * kWakeFileName = "/sys/power/wait_for_fb_wake"; -static char const * const kOldSleepFileName = "/sys/android_power/wait_for_fb_sleep"; -static char const * const kOldWakeFileName = "/sys/android_power/wait_for_fb_wake"; - -// This dir exists if the framebuffer console is present, either built into -// the kernel or loaded as a module. -static char const * const kFbconSysDir = "/sys/class/graphics/fbcon"; - -// ---------------------------------------------------------------------------- - -DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase( - const sp<SurfaceFlinger>& flinger) - : Thread(false), mFlinger(flinger) { -} - -DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() { -} - -// ---------------------------------------------------------------------------- - -DisplayHardwareBase::DisplayEventThread::DisplayEventThread( - const sp<SurfaceFlinger>& flinger) - : DisplayEventThreadBase(flinger) -{ -} - -DisplayHardwareBase::DisplayEventThread::~DisplayEventThread() -{ -} - -bool DisplayHardwareBase::DisplayEventThread::threadLoop() -{ - int err = 0; - char buf; - int fd; - - fd = open(kSleepFileName, O_RDONLY, 0); - do { - err = read(fd, &buf, 1); - } while (err < 0 && errno == EINTR); - close(fd); - LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno)); - if (err >= 0) { - sp<SurfaceFlinger> flinger = mFlinger.promote(); - LOGD("About to give-up screen, flinger = %p", flinger.get()); - if (flinger != 0) { - mBarrier.close(); - flinger->screenReleased(0); - mBarrier.wait(); - } - } - fd = open(kWakeFileName, O_RDONLY, 0); - do { - err = read(fd, &buf, 1); - } while (err < 0 && errno == EINTR); - close(fd); - LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno)); - if (err >= 0) { - sp<SurfaceFlinger> flinger = mFlinger.promote(); - LOGD("Screen about to return, flinger = %p", flinger.get()); - if (flinger != 0) - flinger->screenAcquired(0); - } - return true; -} - -status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const -{ - mBarrier.open(); - return NO_ERROR; -} - -status_t DisplayHardwareBase::DisplayEventThread::readyToRun() -{ - if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) { - if (access(kOldSleepFileName, R_OK) || access(kOldWakeFileName, R_OK)) { - LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName); - return NO_INIT; - } - kSleepFileName = kOldSleepFileName; - kWakeFileName = kOldWakeFileName; - } - return NO_ERROR; -} - -status_t DisplayHardwareBase::DisplayEventThread::initCheck() const -{ - return (((access(kSleepFileName, R_OK) == 0 && - access(kWakeFileName, R_OK) == 0) || - (access(kOldSleepFileName, R_OK) == 0 && - access(kOldWakeFileName, R_OK) == 0)) && - access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT; -} - -// ---------------------------------------------------------------------------- - -pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0; - -DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread( - const sp<SurfaceFlinger>& flinger) - : DisplayEventThreadBase(flinger), consoleFd(-1) -{ - sSignalCatcherPid = 0; - - // create a new console - char const * const ttydev = "/dev/tty0"; - int fd = open(ttydev, O_RDWR | O_SYNC); - if (fd<0) { - LOGE("Can't open %s", ttydev); - this->consoleFd = -errno; - return; - } - - // to make sure that we are in text mode - int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT); - if (res<0) { - LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)", - fd, res, strerror(errno)); - } - - // get the current console - struct vt_stat vs; - res = ioctl(fd, VT_GETSTATE, &vs); - if (res<0) { - LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)", - fd, res, strerror(errno)); - this->consoleFd = -errno; - return; - } - - // switch to console 7 (which is what X normaly uses) - int vtnum = 7; - do { - res = ioctl(fd, VT_ACTIVATE, (void*)vtnum); - } while(res < 0 && errno == EINTR); - if (res<0) { - LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d", - fd, errno, strerror(errno), vtnum); - this->consoleFd = -errno; - return; - } - - do { - res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum); - } while(res < 0 && errno == EINTR); - if (res<0) { - LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d", - fd, res, errno, strerror(errno), vtnum); - this->consoleFd = -errno; - return; - } - - // open the new console - close(fd); - fd = open(ttydev, O_RDWR | O_SYNC); - if (fd<0) { - LOGE("Can't open new console %s", ttydev); - this->consoleFd = -errno; - return; - } - - /* disable console line buffer, echo, ... */ - struct termios ttyarg; - ioctl(fd, TCGETS , &ttyarg); - ttyarg.c_iflag = 0; - ttyarg.c_lflag = 0; - ioctl(fd, TCSETS , &ttyarg); - - // set up signals so we're notified when the console changes - // we can't use SIGUSR1 because it's used by the java-vm - vm.mode = VT_PROCESS; - vm.waitv = 0; - vm.relsig = SIGUSR2; - vm.acqsig = SIGUNUSED; - vm.frsig = 0; - - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_handler = sigHandler; - act.sa_flags = 0; - sigaction(vm.relsig, &act, NULL); - - sigemptyset(&act.sa_mask); - act.sa_handler = sigHandler; - act.sa_flags = 0; - sigaction(vm.acqsig, &act, NULL); - - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, vm.relsig); - sigaddset(&mask, vm.acqsig); - sigprocmask(SIG_BLOCK, &mask, NULL); - - // switch to graphic mode - res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS); - LOGW_IF(res<0, - "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res); - - this->prev_vt_num = vs.v_active; - this->vt_num = vtnum; - this->consoleFd = fd; -} - -DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread() -{ - if (this->consoleFd >= 0) { - int fd = this->consoleFd; - int prev_vt_num = this->prev_vt_num; - int res; - ioctl(fd, KDSETMODE, (void*)KD_TEXT); - do { - res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num); - } while(res < 0 && errno == EINTR); - do { - res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num); - } while(res < 0 && errno == EINTR); - close(fd); - char const * const ttydev = "/dev/tty0"; - fd = open(ttydev, O_RDWR | O_SYNC); - ioctl(fd, VT_DISALLOCATE, 0); - close(fd); - } -} - -status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun() -{ - if (this->consoleFd >= 0) { - sSignalCatcherPid = gettid(); - - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, vm.relsig); - sigaddset(&mask, vm.acqsig); - sigprocmask(SIG_BLOCK, &mask, NULL); - - int res = ioctl(this->consoleFd, VT_SETMODE, &vm); - if (res<0) { - LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)", - this->consoleFd, errno, strerror(errno)); - } - return NO_ERROR; - } - return this->consoleFd; -} - -void DisplayHardwareBase::ConsoleManagerThread::requestExit() -{ - Thread::requestExit(); - if (sSignalCatcherPid != 0) { - // wake the thread up - kill(sSignalCatcherPid, SIGINT); - // wait for it... - } -} - -void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig) -{ - // resend the signal to our signal catcher thread - LOGW("received signal %d in thread %d, resending to %d", - sig, gettid(), sSignalCatcherPid); - - // we absolutely need the delays below because without them - // our main thread never gets a chance to handle the signal. - usleep(10000); - kill(sSignalCatcherPid, sig); - usleep(10000); -} - -status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const -{ - int fd = this->consoleFd; - int err = ioctl(fd, VT_RELDISP, (void*)1); - LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)", - fd, errno, strerror(errno)); - return (err<0) ? (-errno) : status_t(NO_ERROR); -} - -bool DisplayHardwareBase::ConsoleManagerThread::threadLoop() -{ - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, vm.relsig); - sigaddset(&mask, vm.acqsig); - - int sig = 0; - sigwait(&mask, &sig); - - if (sig == vm.relsig) { - sp<SurfaceFlinger> flinger = mFlinger.promote(); - //LOGD("About to give-up screen, flinger = %p", flinger.get()); - if (flinger != 0) - flinger->screenReleased(0); - } else if (sig == vm.acqsig) { - sp<SurfaceFlinger> flinger = mFlinger.promote(); - //LOGD("Screen about to return, flinger = %p", flinger.get()); - if (flinger != 0) - flinger->screenAcquired(0); - } - - return true; -} - -status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const -{ - return consoleFd >= 0 ? NO_ERROR : NO_INIT; -} - -// ---------------------------------------------------------------------------- - -DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger, - uint32_t displayIndex) - : mCanDraw(true) -{ - mDisplayEventThread = new DisplayEventThread(flinger); - if (mDisplayEventThread->initCheck() != NO_ERROR) { - // fall-back on the console - mDisplayEventThread = new ConsoleManagerThread(flinger); - } -} - -DisplayHardwareBase::~DisplayHardwareBase() -{ - // request exit - mDisplayEventThread->requestExitAndWait(); -} - - -bool DisplayHardwareBase::canDraw() const -{ - return mCanDraw; -} - -void DisplayHardwareBase::releaseScreen() const -{ - status_t err = mDisplayEventThread->releaseScreen(); - if (err >= 0) { - //LOGD("screen given-up"); - mCanDraw = false; - } -} - -void DisplayHardwareBase::acquireScreen() const -{ - status_t err = mDisplayEventThread->acquireScreen(); - if (err >= 0) { - //LOGD("screen returned"); - mCanDraw = true; - } -} - -}; // namespace android diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h deleted file mode 100644 index 8369bb8..0000000 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h +++ /dev/null @@ -1,96 +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. - */ - -#ifndef ANDROID_DISPLAY_HARDWARE_BASE_H -#define ANDROID_DISPLAY_HARDWARE_BASE_H - -#include <stdint.h> -#include <utils/RefBase.h> -#include <utils/threads.h> -#include <linux/kd.h> -#include <linux/vt.h> -#include "Barrier.h" - -namespace android { - -class SurfaceFlinger; - -class DisplayHardwareBase -{ -public: - DisplayHardwareBase( - const sp<SurfaceFlinger>& flinger, - uint32_t displayIndex); - - ~DisplayHardwareBase(); - - // console managment - void releaseScreen() const; - void acquireScreen() const; - bool canDraw() const; - -private: - class DisplayEventThreadBase : public Thread { - protected: - wp<SurfaceFlinger> mFlinger; - public: - DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger); - virtual ~DisplayEventThreadBase(); - virtual void onFirstRef() { - run("DisplayEventThread", PRIORITY_URGENT_DISPLAY); - } - virtual status_t acquireScreen() const { return NO_ERROR; }; - virtual status_t releaseScreen() const { return NO_ERROR; }; - virtual status_t initCheck() const = 0; - }; - - class DisplayEventThread : public DisplayEventThreadBase - { - mutable Barrier mBarrier; - public: - DisplayEventThread(const sp<SurfaceFlinger>& flinger); - virtual ~DisplayEventThread(); - virtual bool threadLoop(); - virtual status_t readyToRun(); - virtual status_t releaseScreen() const; - virtual status_t initCheck() const; - }; - - class ConsoleManagerThread : public DisplayEventThreadBase - { - int consoleFd; - int vt_num; - int prev_vt_num; - vt_mode vm; - static void sigHandler(int sig); - static pid_t sSignalCatcherPid; - public: - ConsoleManagerThread(const sp<SurfaceFlinger>& flinger); - virtual ~ConsoleManagerThread(); - virtual bool threadLoop(); - virtual status_t readyToRun(); - virtual void requestExit(); - virtual status_t releaseScreen() const; - virtual status_t initCheck() const; - }; - - sp<DisplayEventThreadBase> mDisplayEventThread; - mutable int mCanDraw; -}; - -}; // namespace android - -#endif // ANDROID_DISPLAY_HARDWARE_BASE_H diff --git a/libs/surfaceflinger/GLExtensions.cpp b/libs/surfaceflinger/GLExtensions.cpp deleted file mode 100644 index 7f4f9fc..0000000 --- a/libs/surfaceflinger/GLExtensions.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> - -#include "GLExtensions.h" - -namespace android { -// --------------------------------------------------------------------------- - -ANDROID_SINGLETON_STATIC_INSTANCE( GLExtensions ) - -GLExtensions::GLExtensions() - : mHaveTextureExternal(false), - mHaveNpot(false), - mHaveDirectTexture(false) -{ -} - -void GLExtensions::initWithGLStrings( - GLubyte const* vendor, - GLubyte const* renderer, - GLubyte const* version, - GLubyte const* extensions, - char const* egl_vendor, - char const* egl_version, - char const* egl_extensions) -{ - mVendor = (char const*)vendor; - mRenderer = (char const*)renderer; - mVersion = (char const*)version; - mExtensions = (char const*)extensions; - mEglVendor = egl_vendor; - mEglVersion = egl_version; - mEglExtensions = egl_extensions; - - char const* curr = (char const*)extensions; - char const* head = curr; - do { - head = strchr(curr, ' '); - String8 s(curr, head ? head-curr : strlen(curr)); - if (s.length()) { - mExtensionList.add(s); - } - curr = head+1; - } while (head); - - curr = egl_extensions; - head = curr; - do { - head = strchr(curr, ' '); - String8 s(curr, head ? head-curr : strlen(curr)); - if (s.length()) { - mExtensionList.add(s); - } - curr = head+1; - } while (head); - -#ifdef EGL_ANDROID_image_native_buffer - if (hasExtension("GL_OES_EGL_image") && - (hasExtension("EGL_KHR_image_base") || hasExtension("EGL_KHR_image")) && - hasExtension("EGL_ANDROID_image_native_buffer")) - { - mHaveDirectTexture = true; - } -#else -#warning "EGL_ANDROID_image_native_buffer not supported" -#endif - - if (hasExtension("GL_ARB_texture_non_power_of_two")) { - mHaveNpot = true; - } - - if (hasExtension("GL_OES_texture_external")) { - mHaveTextureExternal = true; - } else if (strstr(mRenderer.string(), "Adreno")) { - // hack for Adreno 200 - mHaveTextureExternal = true; - } -} - -bool GLExtensions::hasExtension(char const* extension) const -{ - const String8 s(extension); - return mExtensionList.indexOf(s) >= 0; -} - -char const* GLExtensions::getVendor() const { - return mVendor.string(); -} - -char const* GLExtensions::getRenderer() const { - return mRenderer.string(); -} - -char const* GLExtensions::getVersion() const { - return mVersion.string(); -} - -char const* GLExtensions::getExtension() const { - return mExtensions.string(); -} - -char const* GLExtensions::getEglVendor() const { - return mEglVendor.string(); -} - -char const* GLExtensions::getEglVersion() const { - return mEglVersion.string(); -} - -char const* GLExtensions::getEglExtension() const { - return mEglExtensions.string(); -} - - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/libs/surfaceflinger/GLExtensions.h b/libs/surfaceflinger/GLExtensions.h deleted file mode 100644 index bbb284e..0000000 --- a/libs/surfaceflinger/GLExtensions.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#ifndef ANDROID_SF_GLEXTENSION_H -#define ANDROID_SF_GLEXTENSION_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/String8.h> -#include <utils/SortedVector.h> -#include <utils/Singleton.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> -#include <GLES/glext.h> - -namespace android { -// --------------------------------------------------------------------------- - -class GLExtensions : public Singleton<GLExtensions> -{ - friend class Singleton<GLExtensions>; - - bool mHaveTextureExternal : 1; - bool mHaveNpot : 1; - bool mHaveDirectTexture : 1; - - String8 mVendor; - String8 mRenderer; - String8 mVersion; - String8 mExtensions; - String8 mEglVendor; - String8 mEglVersion; - String8 mEglExtensions; - SortedVector<String8> mExtensionList; - - GLExtensions(const GLExtensions&); - GLExtensions& operator = (const GLExtensions&); - -protected: - GLExtensions(); - -public: - inline bool haveTextureExternal() const { - return mHaveTextureExternal; - } - inline bool haveNpot() const { - return mHaveNpot; - } - inline bool haveDirectTexture() const { - return mHaveDirectTexture; - } - - void initWithGLStrings( - GLubyte const* vendor, - GLubyte const* renderer, - GLubyte const* version, - GLubyte const* extensions, - char const* egl_vendor, - char const* egl_version, - char const* egl_extensions); - - char const* getVendor() const; - char const* getRenderer() const; - char const* getVersion() const; - char const* getExtension() const; - - char const* getEglVendor() const; - char const* getEglVersion() const; - char const* getEglExtension() const; - - bool hasExtension(char const* extension) const; -}; - - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SF_GLEXTENSION_H diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp deleted file mode 100644 index 758da4e..0000000 --- a/libs/surfaceflinger/Layer.cpp +++ /dev/null @@ -1,875 +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. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include <cutils/properties.h> -#include <cutils/native_handle.h> - -#include <utils/Errors.h> -#include <utils/Log.h> -#include <utils/StopWatch.h> - -#include <ui/GraphicBuffer.h> -#include <ui/PixelFormat.h> - -#include <surfaceflinger/Surface.h> - -#include "clz.h" -#include "GLExtensions.h" -#include "Layer.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" - - -#define DEBUG_RESIZE 0 - - -namespace android { - -template <typename T> inline T min(T a, T b) { - return a<b ? a : b; -} - -// --------------------------------------------------------------------------- - -Layer::Layer(SurfaceFlinger* flinger, - DisplayID display, const sp<Client>& client) - : LayerBaseClient(flinger, display, client), - mGLExtensions(GLExtensions::getInstance()), - mNeedsBlending(true), - mNeedsDithering(false), - mSecure(false), - mTextureManager(), - mBufferManager(mTextureManager), - mWidth(0), mHeight(0), mFixedSize(false) -{ -} - -Layer::~Layer() -{ - // FIXME: must be called from the main UI thread - EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); - mBufferManager.destroy(dpy); - - // we can use getUserClientUnsafe here because we know we're - // single-threaded at that point. - sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); - if (ourClient != 0) { - ourClient->detachLayer(this); - } -} - -status_t Layer::setToken(const sp<UserClient>& userClient, - SharedClient* sharedClient, int32_t token) -{ - sp<SharedBufferServer> lcblk = new SharedBufferServer( - sharedClient, token, mBufferManager.getDefaultBufferCount(), - getIdentity()); - - status_t err = mUserClientRef.setToken(userClient, lcblk, token); - - LOGE_IF(err != NO_ERROR, - "ClientRef::setToken(%p, %p, %u) failed", - userClient.get(), lcblk.get(), token); - - if (err == NO_ERROR) { - // we need to free the buffers associated with this surface - } - - return err; -} - -int32_t Layer::getToken() const -{ - return mUserClientRef.getToken(); -} - -sp<UserClient> Layer::getClient() const -{ - return mUserClientRef.getClient(); -} - -// called with SurfaceFlinger::mStateLock as soon as the layer is entered -// in the purgatory list -void Layer::onRemoved() -{ - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - if (lcblk) { - // wake up the condition - lcblk->setStatus(NO_INIT); - } -} - -sp<LayerBaseClient::Surface> Layer::createSurface() const -{ - return mSurface; -} - -status_t Layer::ditch() -{ - // NOTE: Called from the main UI thread - - // the layer is not on screen anymore. free as much resources as possible - mFreezeLock.clear(); - - EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); - mBufferManager.destroy(dpy); - mSurface.clear(); - - Mutex::Autolock _l(mLock); - mWidth = mHeight = 0; - return NO_ERROR; -} - -status_t Layer::setBuffers( uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags) -{ - // this surfaces pixel format - PixelFormatInfo info; - status_t err = getPixelFormatInfo(format, &info); - if (err) return err; - - // the display's pixel format - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - uint32_t const maxSurfaceDims = min( - hw.getMaxTextureSize(), hw.getMaxViewportDims()); - - // never allow a surface larger than what our underlying GL implementation - // can handle. - if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { - return BAD_VALUE; - } - - PixelFormatInfo displayInfo; - getPixelFormatInfo(hw.getFormat(), &displayInfo); - const uint32_t hwFlags = hw.getFlags(); - - mFormat = format; - mReqFormat = format; - mWidth = w; - mHeight = h; - mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; - mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; - - // we use the red index - int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); - int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); - mNeedsDithering = layerRedsize > displayRedSize; - - mSurface = new SurfaceLayer(mFlinger, this); - return NO_ERROR; -} - -void Layer::reloadTexture(const Region& dirty) -{ - sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); - if (buffer == NULL) { - // this situation can happen if we ran out of memory for instance. - // not much we can do. continue to use whatever texture was bound - // to this context. - return; - } - - if (mGLExtensions.haveDirectTexture()) { - EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); - if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { - // not sure what we can do here... - goto slowpath; - } - } else { -slowpath: - GGLSurface t; - status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); - LOGE_IF(res, "error %d (%s) locking buffer %p", - res, strerror(res), buffer.get()); - if (res == NO_ERROR) { - mBufferManager.loadTexture(dirty, t); - buffer->unlock(); - } - } -} - -void Layer::onDraw(const Region& clip) const -{ - Texture tex(mBufferManager.getActiveTexture()); - if (tex.name == -1LU) { - // the texture has not been created yet, this Layer has - // in fact never been drawn into. This happens frequently with - // SurfaceView because the WindowManager can't know when the client - // has drawn the first time. - - // If there is nothing under us, we paint the screen in black, otherwise - // we just skip this update. - - // figure out if there is something below us - Region under; - const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); - const size_t count = drawingLayers.size(); - for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer(drawingLayers[i]); - if (layer.get() == static_cast<LayerBase const*>(this)) - break; - under.orSelf(layer->visibleRegionScreen); - } - // if not everything below us is covered, we plug the holes! - Region holes(clip.subtract(under)); - if (!holes.isEmpty()) { - clearWithOpenGL(holes, 0, 0, 0, 1); - } - return; - } - drawWithOpenGL(clip, tex); -} - -bool Layer::needsFiltering() const -{ - if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { - // NOTE: there is a race here, because mFixedSize is updated in a - // binder transaction. however, it doesn't really matter since it is - // evaluated each time we draw. To be perfectly correct, this flag - // would have to be associated with a buffer. - if (mFixedSize) - return true; - } - return LayerBase::needsFiltering(); -} - - -status_t Layer::setBufferCount(int bufferCount) -{ - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - if (!lcblk) { - // oops, the client is already gone - return DEAD_OBJECT; - } - - // NOTE: lcblk->resize() is protected by an internal lock - status_t err = lcblk->resize(bufferCount); - if (err == NO_ERROR) - mBufferManager.resize(bufferCount); - - return err; -} - -sp<GraphicBuffer> Layer::requestBuffer(int index, - uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, - uint32_t usage) -{ - sp<GraphicBuffer> buffer; - - if (int32_t(reqWidth | reqHeight | reqFormat) < 0) - return buffer; - - if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) - return buffer; - - // this ensures our client doesn't go away while we're accessing - // the shared area. - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - if (!lcblk) { - // oops, the client is already gone - return buffer; - } - - /* - * This is called from the client's Surface::dequeue(). This can happen - * at any time, especially while we're in the middle of using the - * buffer 'index' as our front buffer. - * - * Make sure the buffer we're resizing is not the front buffer and has been - * dequeued. Once this condition is asserted, we are guaranteed that this - * buffer cannot become the front buffer under our feet, since we're called - * from Surface::dequeue() - */ - status_t err = lcblk->assertReallocate(index); - LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); - if (err != NO_ERROR) { - // the surface may have died - return buffer; - } - - uint32_t w, h, f; - { // scope for the lock - Mutex::Autolock _l(mLock); - const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight); - const bool formatChanged = mReqFormat != reqFormat; - mReqWidth = reqWidth; - mReqHeight = reqHeight; - mReqFormat = reqFormat; - mFixedSize = reqWidth && reqHeight; - w = reqWidth ? reqWidth : mWidth; - h = reqHeight ? reqHeight : mHeight; - f = reqFormat ? reqFormat : mFormat; - buffer = mBufferManager.detachBuffer(index); - if (fixedSizeChanged || formatChanged) { - lcblk->reallocateAllExcept(index); - } - } - - const uint32_t effectiveUsage = getEffectiveUsage(usage); - if (buffer!=0 && buffer->getStrongCount() == 1) { - err = buffer->reallocate(w, h, f, effectiveUsage); - } else { - // here we have to reallocate a new buffer because we could have a - // client in our process with a reference to it (eg: status bar), - // and we can't release the handle under its feet. - buffer.clear(); - buffer = new GraphicBuffer(w, h, f, effectiveUsage); - err = buffer->initCheck(); - } - - if (err || buffer->handle == 0) { - LOGE_IF(err || buffer->handle == 0, - "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", - this, index, w, h, strerror(-err)); - } else { - LOGD_IF(DEBUG_RESIZE, - "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", - this, index, w, h, buffer->handle); - } - - if (err == NO_ERROR && buffer->handle != 0) { - Mutex::Autolock _l(mLock); - mBufferManager.attachBuffer(index, buffer); - } - return buffer; -} - -uint32_t Layer::getEffectiveUsage(uint32_t usage) const -{ - /* - * buffers used for software rendering, but h/w composition - * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE - * - * buffers used for h/w rendering and h/w composition - * are allocated with HW_RENDER | HW_TEXTURE - * - * buffers used with h/w rendering and either NPOT or no egl_image_ext - * are allocated with SW_READ_RARELY | HW_RENDER - * - */ - - if (mSecure) { - // secure buffer, don't store it into the GPU - usage = GraphicBuffer::USAGE_SW_READ_OFTEN | - GraphicBuffer::USAGE_SW_WRITE_OFTEN; - } else { - // it's allowed to modify the usage flags here, but generally - // the requested flags should be honored. - // request EGLImage for all buffers - usage |= GraphicBuffer::USAGE_HW_TEXTURE; - } - return usage; -} - -uint32_t Layer::doTransaction(uint32_t flags) -{ - const Layer::State& front(drawingState()); - const Layer::State& temp(currentState()); - - const bool sizeChanged = (front.requested_w != temp.requested_w) || - (front.requested_h != temp.requested_h); - - if (sizeChanged) { - // the size changed, we need to ask our client to request a new buffer - LOGD_IF(DEBUG_RESIZE, - "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", - this, - int(temp.requested_w), int(temp.requested_h), - int(front.requested_w), int(front.requested_h)); - - if (!isFixedSize()) { - // we're being resized and there is a freeze display request, - // acquire a freeze lock, so that the screen stays put - // until we've redrawn at the new size; this is to avoid - // glitches upon orientation changes. - if (mFlinger->hasFreezeRequest()) { - // if the surface is hidden, don't try to acquire the - // freeze lock, since hidden surfaces may never redraw - if (!(front.flags & ISurfaceComposer::eLayerHidden)) { - mFreezeLock = mFlinger->getFreezeLock(); - } - } - - // this will make sure LayerBase::doTransaction doesn't update - // the drawing state's size - Layer::State& editDraw(mDrawingState); - editDraw.requested_w = temp.requested_w; - editDraw.requested_h = temp.requested_h; - - // record the new size, form this point on, when the client request - // a buffer, it'll get the new size. - setBufferSize(temp.requested_w, temp.requested_h); - - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - if (lcblk) { - // all buffers need reallocation - lcblk->reallocateAll(); - } - } else { - // record the new size - setBufferSize(temp.requested_w, temp.requested_h); - } - } - - if (temp.sequence != front.sequence) { - if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { - // this surface is now hidden, so it shouldn't hold a freeze lock - // (it may never redraw, which is fine if it is hidden) - mFreezeLock.clear(); - } - } - - return LayerBase::doTransaction(flags); -} - -void Layer::setBufferSize(uint32_t w, uint32_t h) { - Mutex::Autolock _l(mLock); - mWidth = w; - mHeight = h; -} - -bool Layer::isFixedSize() const { - Mutex::Autolock _l(mLock); - return mFixedSize; -} - -// ---------------------------------------------------------------------------- -// pageflip handling... -// ---------------------------------------------------------------------------- - -void Layer::lockPageFlip(bool& recomputeVisibleRegions) -{ - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - if (!lcblk) { - // client died - recomputeVisibleRegions = true; - return; - } - - ssize_t buf = lcblk->retireAndLock(); - if (buf == NOT_ENOUGH_DATA) { - // NOTE: This is not an error, it simply means there is nothing to - // retire. The buffer is locked because we will use it - // for composition later in the loop - return; - } - - if (buf < NO_ERROR) { - LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); - mPostedDirtyRegion.clear(); - return; - } - - // we retired a buffer, which becomes the new front buffer - if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { - LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); - mPostedDirtyRegion.clear(); - return; - } - - // get the dirty region - sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); - if (newFrontBuffer != NULL) { - // compute the posted region - const Region dirty(lcblk->getDirtyRegion(buf)); - mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); - - // update the layer size and release freeze-lock - const Layer::State& front(drawingState()); - if (newFrontBuffer->getWidth() == front.requested_w && - newFrontBuffer->getHeight() == front.requested_h) - { - if ((front.w != front.requested_w) || - (front.h != front.requested_h)) - { - // Here we pretend the transaction happened by updating the - // current and drawing states. Drawing state is only accessed - // in this thread, no need to have it locked - Layer::State& editDraw(mDrawingState); - editDraw.w = editDraw.requested_w; - editDraw.h = editDraw.requested_h; - - // We also need to update the current state so that we don't - // end-up doing too much work during the next transaction. - // NOTE: We actually don't need hold the transaction lock here - // because State::w and State::h are only accessed from - // this thread - Layer::State& editTemp(currentState()); - editTemp.w = editDraw.w; - editTemp.h = editDraw.h; - - // recompute visible region - recomputeVisibleRegions = true; - } - - // we now have the correct size, unfreeze the screen - mFreezeLock.clear(); - } - } else { - // this should not happen unless we ran out of memory while - // allocating the buffer. we're hoping that things will get back - // to normal the next time the app tries to draw into this buffer. - // meanwhile, pretend the screen didn't update. - mPostedDirtyRegion.clear(); - } - - if (lcblk->getQueuedCount()) { - // signal an event if we have more buffers waiting - mFlinger->signalEvent(); - } - - /* a buffer was posted, so we need to call reloadTexture(), which - * will update our internal data structures (eg: EGLImageKHR or - * texture names). we need to do this even if mPostedDirtyRegion is - * empty -- it's orthogonal to the fact that a new buffer was posted, - * for instance, a degenerate case could be that the user did an empty - * update but repainted the buffer with appropriate content (after a - * resize for instance). - */ - reloadTexture( mPostedDirtyRegion ); -} - -void Layer::unlockPageFlip( - const Transform& planeTransform, Region& outDirtyRegion) -{ - Region dirtyRegion(mPostedDirtyRegion); - if (!dirtyRegion.isEmpty()) { - mPostedDirtyRegion.clear(); - // The dirty region is given in the layer's coordinate space - // transform the dirty region by the surface's transformation - // and the global transformation. - const Layer::State& s(drawingState()); - const Transform tr(planeTransform * s.transform); - dirtyRegion = tr.transform(dirtyRegion); - - // At this point, the dirty region is in screen space. - // Make sure it's constrained by the visible region (which - // is in screen space as well). - dirtyRegion.andSelf(visibleRegionScreen); - outDirtyRegion.orSelf(dirtyRegion); - } - if (visibleRegionScreen.isEmpty()) { - // an invisible layer should not hold a freeze-lock - // (because it may never be updated and therefore never release it) - mFreezeLock.clear(); - } -} - -void Layer::finishPageFlip() -{ - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - if (lcblk) { - int buf = mBufferManager.getActiveBufferIndex(); - if (buf >= 0) { - status_t err = lcblk->unlock( buf ); - LOGE_IF(err!=NO_ERROR, - "layer %p, buffer=%d wasn't locked!", - this, buf); - } - } -} - - -void Layer::dump(String8& result, char* buffer, size_t SIZE) const -{ - LayerBaseClient::dump(result, buffer, SIZE); - - ClientRef::Access sharedClient(mUserClientRef); - SharedBufferServer* lcblk(sharedClient.get()); - uint32_t totalTime = 0; - if (lcblk) { - SharedBufferStack::Statistics stats = lcblk->getStats(); - totalTime= stats.totalTime; - result.append( lcblk->dump(" ") ); - } - - sp<const GraphicBuffer> buf0(getBuffer(0)); - sp<const GraphicBuffer> buf1(getBuffer(1)); - uint32_t w0=0, h0=0, s0=0; - uint32_t w1=0, h1=0, s1=0; - if (buf0 != 0) { - w0 = buf0->getWidth(); - h0 = buf0->getHeight(); - s0 = buf0->getStride(); - } - if (buf1 != 0) { - w1 = buf1->getWidth(); - h1 = buf1->getHeight(); - s1 = buf1->getStride(); - } - snprintf(buffer, SIZE, - " " - "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," - " freezeLock=%p, dq-q-time=%u us\n", - mFormat, w0, h0, s0, w1, h1, s1, - getFreezeLock().get(), totalTime); - - result.append(buffer); -} - -// --------------------------------------------------------------------------- - -Layer::ClientRef::ClientRef() - : mControlBlock(0), mToken(-1) { -} - -Layer::ClientRef::~ClientRef() { -} - -int32_t Layer::ClientRef::getToken() const { - Mutex::Autolock _l(mLock); - return mToken; -} - -sp<UserClient> Layer::ClientRef::getClient() const { - Mutex::Autolock _l(mLock); - return mUserClient.promote(); -} - -status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, - const sp<SharedBufferServer>& sharedClient, int32_t token) { - Mutex::Autolock _l(mLock); - - { // scope for strong mUserClient reference - sp<UserClient> userClient(mUserClient.promote()); - if (mUserClient != 0 && mControlBlock != 0) { - mControlBlock->setStatus(NO_INIT); - } - } - - mUserClient = uc; - mToken = token; - mControlBlock = sharedClient; - return NO_ERROR; -} - -sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { - return mUserClient.promote(); -} - -// this class gives us access to SharedBufferServer safely -// it makes sure the UserClient (and its associated shared memory) -// won't go away while we're accessing it. -Layer::ClientRef::Access::Access(const ClientRef& ref) - : mControlBlock(0) -{ - Mutex::Autolock _l(ref.mLock); - mUserClientStrongRef = ref.mUserClient.promote(); - if (mUserClientStrongRef != 0) - mControlBlock = ref.mControlBlock; -} - -Layer::ClientRef::Access::~Access() -{ -} - -// --------------------------------------------------------------------------- - -Layer::BufferManager::BufferManager(TextureManager& tm) - : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), - mActiveBuffer(-1), mFailover(false) -{ -} - -Layer::BufferManager::~BufferManager() -{ -} - -status_t Layer::BufferManager::resize(size_t size) -{ - Mutex::Autolock _l(mLock); - mNumBuffers = size; - return NO_ERROR; -} - -// only for debugging -sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { - return mBufferData[index].buffer; -} - -status_t Layer::BufferManager::setActiveBufferIndex(size_t index) { - mActiveBuffer = index; - return NO_ERROR; -} - -size_t Layer::BufferManager::getActiveBufferIndex() const { - return mActiveBuffer; -} - -Texture Layer::BufferManager::getActiveTexture() const { - Texture res; - if (mFailover || mActiveBuffer<0) { - res = mFailoverTexture; - } else { - static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; - } - return res; -} - -sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { - sp<GraphicBuffer> result; - const ssize_t activeBuffer = mActiveBuffer; - if (activeBuffer >= 0) { - BufferData const * const buffers = mBufferData; - Mutex::Autolock _l(mLock); - result = buffers[activeBuffer].buffer; - } - return result; -} - -sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) -{ - BufferData* const buffers = mBufferData; - sp<GraphicBuffer> buffer; - Mutex::Autolock _l(mLock); - buffer = buffers[index].buffer; - buffers[index].buffer = 0; - return buffer; -} - -status_t Layer::BufferManager::attachBuffer(size_t index, - const sp<GraphicBuffer>& buffer) -{ - BufferData* const buffers = mBufferData; - Mutex::Autolock _l(mLock); - buffers[index].buffer = buffer; - buffers[index].texture.dirty = true; - return NO_ERROR; -} - -status_t Layer::BufferManager::destroy(EGLDisplay dpy) -{ - BufferData* const buffers = mBufferData; - size_t num; - { // scope for the lock - Mutex::Autolock _l(mLock); - num = mNumBuffers; - for (size_t i=0 ; i<num ; i++) { - buffers[i].buffer = 0; - } - } - for (size_t i=0 ; i<num ; i++) { - destroyTexture(&buffers[i].texture, dpy); - } - destroyTexture(&mFailoverTexture, dpy); - return NO_ERROR; -} - -status_t Layer::BufferManager::initEglImage(EGLDisplay dpy, - const sp<GraphicBuffer>& buffer) -{ - status_t err = NO_INIT; - ssize_t index = mActiveBuffer; - if (index >= 0) { - if (!mFailover) { - Image& texture(mBufferData[index].texture); - err = mTextureManager.initEglImage(&texture, dpy, buffer); - // if EGLImage fails, we switch to regular texture mode, and we - // free all resources associated with using EGLImages. - if (err == NO_ERROR) { - mFailover = false; - destroyTexture(&mFailoverTexture, dpy); - } else { - mFailover = true; - const size_t num = mNumBuffers; - for (size_t i=0 ; i<num ; i++) { - destroyTexture(&mBufferData[i].texture, dpy); - } - } - } else { - // we failed once, don't try again - err = BAD_VALUE; - } - } - return err; -} - -status_t Layer::BufferManager::loadTexture( - const Region& dirty, const GGLSurface& t) -{ - return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); -} - -status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) -{ - if (tex->name != -1U) { - glDeleteTextures(1, &tex->name); - tex->name = -1U; - } - if (tex->image != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(dpy, tex->image); - tex->image = EGL_NO_IMAGE_KHR; - } - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - -Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, - const sp<Layer>& owner) - : Surface(flinger, owner->getIdentity(), owner) -{ -} - -Layer::SurfaceLayer::~SurfaceLayer() -{ -} - -sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) -{ - sp<GraphicBuffer> buffer; - sp<Layer> owner(getOwner()); - if (owner != 0) { - /* - * requestBuffer() cannot be called from the main thread - * as it could cause a dead-lock, since it may have to wait - * on conditions updated my the main thread. - */ - buffer = owner->requestBuffer(index, w, h, format, usage); - } - return buffer; -} - -status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) -{ - status_t err = DEAD_OBJECT; - sp<Layer> owner(getOwner()); - if (owner != 0) { - /* - * setBufferCount() cannot be called from the main thread - * as it could cause a dead-lock, since it may have to wait - * on conditions updated my the main thread. - */ - err = owner->setBufferCount(bufferCount); - } - return err; -} - -// --------------------------------------------------------------------------- - - -}; // namespace android diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h deleted file mode 100644 index e1d283b..0000000 --- a/libs/surfaceflinger/Layer.h +++ /dev/null @@ -1,239 +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. - */ - -#ifndef ANDROID_LAYER_H -#define ANDROID_LAYER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <ui/GraphicBuffer.h> -#include <ui/PixelFormat.h> -#include <pixelflinger/pixelflinger.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> -#include <GLES/glext.h> - -#include "LayerBase.h" -#include "Transform.h" -#include "TextureManager.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class FreezeLock; -class Client; -class GLExtensions; -class UserClient; - -// --------------------------------------------------------------------------- - -class Layer : public LayerBaseClient -{ -public: - Layer(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - - virtual ~Layer(); - - virtual const char* getTypeId() const { return "Layer"; } - - // the this layer's size and format - status_t setBuffers(uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags=0); - - // associate a UserClient to this Layer - status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx); - int32_t getToken() const; - sp<UserClient> getClient() const; - - // Set this Layer's buffers size - void setBufferSize(uint32_t w, uint32_t h); - bool isFixedSize() const; - - // LayerBase interface - virtual void onDraw(const Region& clip) const; - virtual uint32_t doTransaction(uint32_t transactionFlags); - virtual void lockPageFlip(bool& recomputeVisibleRegions); - virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); - virtual void finishPageFlip(); - virtual bool needsBlending() const { return mNeedsBlending; } - virtual bool needsDithering() const { return mNeedsDithering; } - virtual bool needsFiltering() const; - virtual bool isSecure() const { return mSecure; } - virtual sp<Surface> createSurface() const; - virtual status_t ditch(); - virtual void onRemoved(); - - // only for debugging - inline sp<GraphicBuffer> getBuffer(int i) const { - return mBufferManager.getBuffer(i); } - // only for debugging - inline const sp<FreezeLock>& getFreezeLock() const { - return mFreezeLock; } - -protected: - virtual void dump(String8& result, char* scratch, size_t size) const; - -private: - void reloadTexture(const Region& dirty); - uint32_t getEffectiveUsage(uint32_t usage) const; - sp<GraphicBuffer> requestBuffer(int bufferIdx, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage); - status_t setBufferCount(int bufferCount); - - // ----------------------------------------------------------------------- - - class SurfaceLayer : public LayerBaseClient::Surface { - public: - SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner); - ~SurfaceLayer(); - private: - virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage); - virtual status_t setBufferCount(int bufferCount); - sp<Layer> getOwner() const { - return static_cast<Layer*>(Surface::getOwner().get()); - } - }; - friend class SurfaceLayer; - - // ----------------------------------------------------------------------- - - class ClientRef { - ClientRef(const ClientRef& rhs); - ClientRef& operator = (const ClientRef& rhs); - mutable Mutex mLock; - // binder thread, page-flip thread - sp<SharedBufferServer> mControlBlock; - wp<UserClient> mUserClient; - int32_t mToken; - public: - ClientRef(); - ~ClientRef(); - int32_t getToken() const; - sp<UserClient> getClient() const; - status_t setToken(const sp<UserClient>& uc, - const sp<SharedBufferServer>& sharedClient, int32_t token); - sp<UserClient> getUserClientUnsafe() const; - class Access { - Access(const Access& rhs); - Access& operator = (const Access& rhs); - sp<UserClient> mUserClientStrongRef; - sp<SharedBufferServer> mControlBlock; - public: - Access(const ClientRef& ref); - ~Access(); - inline SharedBufferServer* get() const { return mControlBlock.get(); } - }; - friend class Access; - }; - - // ----------------------------------------------------------------------- - - class BufferManager { - static const size_t NUM_BUFFERS = 2; - struct BufferData { - sp<GraphicBuffer> buffer; - Image texture; - }; - // this lock protect mBufferData[].buffer but since there - // is very little contention, we have only one like for - // the whole array, we also use it to protect mNumBuffers. - mutable Mutex mLock; - BufferData mBufferData[SharedBufferStack::NUM_BUFFER_MAX]; - size_t mNumBuffers; - Texture mFailoverTexture; - TextureManager& mTextureManager; - ssize_t mActiveBuffer; - bool mFailover; - static status_t destroyTexture(Image* tex, EGLDisplay dpy); - - public: - static size_t getDefaultBufferCount() { return NUM_BUFFERS; } - BufferManager(TextureManager& tm); - ~BufferManager(); - - // detach/attach buffer from/to given index - sp<GraphicBuffer> detachBuffer(size_t index); - status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer); - // resize the number of active buffers - status_t resize(size_t size); - - // ---------------------------------------------- - // must be called from GL thread - - // set/get active buffer index - status_t setActiveBufferIndex(size_t index); - size_t getActiveBufferIndex() const; - // return the active buffer - sp<GraphicBuffer> getActiveBuffer() const; - // return the active texture (or fail-over) - Texture getActiveTexture() const; - // frees resources associated with all buffers - status_t destroy(EGLDisplay dpy); - // load bitmap data into the active buffer - status_t loadTexture(const Region& dirty, const GGLSurface& t); - // make active buffer an EGLImage if needed - status_t initEglImage(EGLDisplay dpy, - const sp<GraphicBuffer>& buffer); - - // ---------------------------------------------- - // only for debugging - sp<GraphicBuffer> getBuffer(size_t index) const; - }; - - // ----------------------------------------------------------------------- - - // thread-safe - ClientRef mUserClientRef; - - // constants - sp<Surface> mSurface; - PixelFormat mFormat; - const GLExtensions& mGLExtensions; - bool mNeedsBlending; - bool mNeedsDithering; - - // page-flip thread (currently main thread) - bool mSecure; - Region mPostedDirtyRegion; - - // page-flip thread and transaction thread (currently main thread) - sp<FreezeLock> mFreezeLock; - - // see threading usage in declaration - TextureManager mTextureManager; - BufferManager mBufferManager; - - // binder thread, transaction thread - mutable Mutex mLock; - uint32_t mWidth; - uint32_t mHeight; - uint32_t mReqWidth; - uint32_t mReqHeight; - uint32_t mReqFormat; - bool mFixedSize; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_H diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp deleted file mode 100644 index d5aa53f..0000000 --- a/libs/surfaceflinger/LayerBase.cpp +++ /dev/null @@ -1,593 +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. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/Log.h> -#include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> - -#include <GLES/gl.h> -#include <GLES/glext.h> - -#include <hardware/hardware.h> - -#include "clz.h" -#include "LayerBase.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" -#include "TextureManager.h" - - -namespace android { - -// --------------------------------------------------------------------------- - -LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) - : dpy(display), contentDirty(false), - mFlinger(flinger), - mNeedsFiltering(false), - mOrientation(0), - mLeft(0), mTop(0), - mTransactionFlags(0), - mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), - mInvalidate(0) -{ - const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); - mFlags = hw.getFlags(); -} - -LayerBase::~LayerBase() -{ -} - -void LayerBase::setName(const String8& name) { - mName = name; -} - -String8 LayerBase::getName() const { - return mName; -} - -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.requested_w = w; - mCurrentState.requested_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() { - mDrawingState = mCurrentState; -} -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); -} - -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.requested_w == w && mCurrentState.requested_h == h) - return false; - mCurrentState.requested_w = w; - mCurrentState.requested_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) { - mCurrentState.sequence++; - mCurrentState.transform.set( - matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); - requestTransaction(); - return true; -} -bool LayerBase::setTransparentRegionHint(const Region& transparent) { - 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 ((front.requested_w != temp.requested_w) || - (front.requested_h != temp.requested_h)) { - // resize the layer, set the physical size to the requested size - Layer::State& editTemp(currentState()); - editTemp.w = temp.requested_w; - editTemp.h = temp.requested_h; - } - - if ((front.w != temp.w) || (front.h != temp.h)) { - // invalidate and recompute the visible regions if needed - flags |= Layer::eVisibleRegion; - } - - if (temp.sequence != front.sequence) { - // invalidate and recompute the visible regions if needed - flags |= eVisibleRegion; - this->contentDirty = true; - - mNeedsFiltering = false; - if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { - // we may use linear filtering, if the matrix scales us - const uint8_t type = temp.transform.getType(); - if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) { - mNeedsFiltering = true; - } - } - } - - // Commit the transaction - commitTransaction(); - return flags; -} - -void LayerBase::validateVisibility(const Transform& planeTransform) -{ - const Layer::State& s(drawingState()); - const Transform tr(planeTransform * s.transform); - const bool transformed = tr.transformed(); - - uint32_t w = s.w; - uint32_t h = s.h; - 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); - mLeft = tr.tx(); - mTop = tr.ty(); -} - -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::const_iterator it = reg.begin(); - Region::const_iterator const end = reg.end(); - if (it != end) { - 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 (it != end) { - const Rect& r = *it++; - 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); -} - -void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red, - GLclampf green, GLclampf blue, - GLclampf alpha) const -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t fbHeight = hw.getHeight(); - glColor4f(red,green,blue,alpha); - - TextureManager::deactivateTextures(); - - glDisable(GL_BLEND); - glDisable(GL_DITHER); - - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - glEnable(GL_SCISSOR_TEST); - glVertexPointer(2, GL_FLOAT, 0, mVertices); - while (it != end) { - const Rect& r = *it++; - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } -} - -void LayerBase::clearWithOpenGL(const Region& clip) const -{ - clearWithOpenGL(clip,0,0,0,0); -} - -void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t fbHeight = hw.getHeight(); - const State& s(drawingState()); - - // bind our texture - TextureManager::activateTexture(texture, needsFiltering()); - uint32_t width = texture.width; - uint32_t height = texture.height; - - GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; - if (UNLIKELY(s.alpha < 0xFF)) { - const GLfloat alpha = s.alpha * (1.0f/255.0f); - if (mPremultipliedAlpha) { - glColor4f(alpha, alpha, alpha, alpha); - } else { - glColor4f(1, 1, 1, alpha); - } - glEnable(GL_BLEND); - glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } else { - glColor4f(1, 1, 1, 1); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - if (needsBlending()) { - glEnable(GL_BLEND); - glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - } - - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - const GLfloat texCoords[4][2] = { - { 0, 0 }, - { 0, 1 }, - { 1, 1 }, - { 1, 0 } - }; - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - // the texture's source is rotated - switch (texture.transform) { - case HAL_TRANSFORM_ROT_90: - glTranslatef(0, 1, 0); - glRotatef(-90, 0, 0, 1); - break; - case HAL_TRANSFORM_ROT_180: - glTranslatef(1, 1, 0); - glRotatef(-180, 0, 0, 1); - break; - case HAL_TRANSFORM_ROT_270: - glTranslatef(1, 0, 0); - glRotatef(-270, 0, 0, 1); - break; - } - - if (texture.NPOTAdjust) { - glScalef(texture.wScale, texture.hScale, 1.0f); - } - - if (needsDithering()) { - glEnable(GL_DITHER); - } else { - glDisable(GL_DITHER); - } - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, mVertices); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - - while (it != end) { - const Rect& r = *it++; - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const -{ - const Layer::State& s(drawingState()); - snprintf(buffer, SIZE, - "+ %s %p\n" - " " - "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), " - "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, " - "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", - getTypeId(), this, s.z, tx(), ty(), s.w, s.h, - needsBlending(), needsDithering(), contentDirty, - s.alpha, s.flags, - s.transform[0][0], s.transform[0][1], - s.transform[1][0], s.transform[1][1]); - result.append(buffer); -} - -// --------------------------------------------------------------------------- - -int32_t LayerBaseClient::sIdentity = 1; - -LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBase(flinger, display), mClientRef(client), - mIdentity(uint32_t(android_atomic_inc(&sIdentity))) -{ -} - -LayerBaseClient::~LayerBaseClient() -{ - sp<Client> c(mClientRef.promote()); - if (c != 0) { - c->detachLayer(this); - } -} - -sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() -{ - sp<Surface> s; - Mutex::Autolock _l(mLock); - s = mClientSurface.promote(); - if (s == 0) { - s = createSurface(); - mClientSurface = s; - } - return s; -} - -sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const -{ - return new Surface(mFlinger, mIdentity, - const_cast<LayerBaseClient *>(this)); -} - -void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const -{ - LayerBase::dump(result, buffer, SIZE); - - sp<Client> client(mClientRef.promote()); - snprintf(buffer, SIZE, - " name=%s\n" - " client=%p, identity=%u\n", - getName().string(), - client.get(), getIdentity()); - - result.append(buffer); -} - -// --------------------------------------------------------------------------- - -LayerBaseClient::Surface::Surface( - const sp<SurfaceFlinger>& flinger, - int identity, - const sp<LayerBaseClient>& owner) - : mFlinger(flinger), mIdentity(identity), mOwner(owner) -{ -} - -LayerBaseClient::Surface::~Surface() -{ - /* - * This is a good place to clean-up all client resources - */ - - // destroy client resources - sp<LayerBaseClient> layer = getOwner(); - if (layer != 0) { - mFlinger->destroySurface(layer); - } -} - -sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const { - sp<LayerBaseClient> owner(mOwner.promote()); - return owner; -} - -status_t LayerBaseClient::Surface::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case REGISTER_BUFFERS: - case UNREGISTER_BUFFERS: - case CREATE_OVERLAY: - { - if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - LOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - } - } - return BnSurface::onTransact(code, data, reply, flags); -} - -sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int bufferIdx, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) -{ - return NULL; -} - -status_t LayerBaseClient::Surface::setBufferCount(int bufferCount) -{ - return INVALID_OPERATION; -} - -status_t LayerBaseClient::Surface::registerBuffers( - const ISurface::BufferHeap& buffers) -{ - return INVALID_OPERATION; -} - -void LayerBaseClient::Surface::postBuffer(ssize_t offset) -{ -} - -void LayerBaseClient::Surface::unregisterBuffers() -{ -} - -sp<OverlayRef> LayerBaseClient::Surface::createOverlay( - uint32_t w, uint32_t h, int32_t format, int32_t orientation) -{ - return NULL; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h deleted file mode 100644 index 4288cf7..0000000 --- a/libs/surfaceflinger/LayerBase.h +++ /dev/null @@ -1,333 +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. - */ - -#ifndef ANDROID_LAYER_BASE_H -#define ANDROID_LAYER_BASE_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> - -#include <utils/RefBase.h> - -#include <ui/Region.h> -#include <ui/Overlay.h> - -#include <surfaceflinger/ISurfaceComposerClient.h> -#include <private/surfaceflinger/SharedBufferStack.h> -#include <private/surfaceflinger/LayerState.h> - -#include <pixelflinger/pixelflinger.h> - -#include "Transform.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class DisplayHardware; -class Client; -class GraphicBuffer; -class GraphicPlane; -class LayerBaseClient; -class SurfaceFlinger; -class Texture; - -// --------------------------------------------------------------------------- - -class LayerBase : public RefBase -{ -public: - LayerBase(SurfaceFlinger* flinger, DisplayID display); - - DisplayID dpy; - mutable bool contentDirty; - Region visibleRegionScreen; - Region transparentRegionScreen; - Region coveredRegionScreen; - - struct State { - uint32_t w; - uint32_t h; - uint32_t requested_w; - uint32_t requested_h; - uint32_t z; - uint8_t alpha; - uint8_t flags; - uint8_t reserved[2]; - int32_t sequence; // changes when visible regions can change - uint32_t tint; - Transform transform; - Region transparentRegion; - }; - - void setName(const String8& name); - String8 getName() const; - - // modify current state - bool setPosition(int32_t x, int32_t y); - bool setLayer(uint32_t z); - bool setSize(uint32_t w, uint32_t h); - bool setAlpha(uint8_t alpha); - bool setMatrix(const layer_state_t::matrix22_t& matrix); - bool setTransparentRegionHint(const Region& opaque); - bool setFlags(uint8_t flags, uint8_t mask); - - void commitTransaction(); - bool requestTransaction(); - void forceVisibilityTransaction(); - - uint32_t getTransactionFlags(uint32_t flags); - uint32_t setTransactionFlags(uint32_t flags); - - Rect visibleBounds() const; - void drawRegion(const Region& reg) const; - - void invalidate(); - - virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; } - - virtual const char* getTypeId() const { return "LayerBase"; } - - /** - * draw - performs some global clipping optimizations - * and calls onDraw(). - * Typically this method is not overridden, instead implement onDraw() - * to perform the actual drawing. - */ - virtual void draw(const Region& clip) const; - - /** - * onDraw - draws the surface. - */ - virtual void onDraw(const Region& clip) const = 0; - - /** - * initStates - called just after construction - */ - virtual void initStates(uint32_t w, uint32_t h, uint32_t flags); - - /** - * doTransaction - process the transaction. This is a good place to figure - * out which attributes of the surface have changed. - */ - virtual uint32_t doTransaction(uint32_t transactionFlags); - - /** - * setVisibleRegion - called to set the new visible region. This gives - * a chance to update the new visible region or record the fact it changed. - */ - virtual void setVisibleRegion(const Region& visibleRegion); - - /** - * setCoveredRegion - called when the covered region changes. The covered - * region corresponds to any area of the surface that is covered - * (transparently or not) by another surface. - */ - virtual void setCoveredRegion(const Region& coveredRegion); - - /** - * validateVisibility - cache a bunch of things - */ - virtual void validateVisibility(const Transform& globalTransform); - - /** - * lockPageFlip - called each time the screen is redrawn and returns whether - * the visible regions need to be recomputed (this is a fairly heavy - * operation, so this should be set only if needed). Typically this is used - * to figure out if the content or size of a surface has changed. - */ - virtual void lockPageFlip(bool& recomputeVisibleRegions); - - /** - * unlockPageFlip - called each time the screen is redrawn. updates the - * final dirty region wrt the planeTransform. - * At this point, all visible regions, surface position and size, etc... are - * correct. - */ - virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); - - /** - * finishPageFlip - called after all surfaces have drawn. - */ - virtual void finishPageFlip(); - - /** - * needsBlending - true if this surface needs blending - */ - virtual bool needsBlending() const { return false; } - - /** - * needsDithering - true if this surface needs dithering - */ - virtual bool needsDithering() const { return false; } - - /** - * needsLinearFiltering - true if this surface needs filtering - */ - virtual bool needsFiltering() const { return mNeedsFiltering; } - - /** - * isSecure - true if this surface is secure, that is if it prevents - * screenshots or VNC servers. - */ - virtual bool isSecure() const { return false; } - - /** Called from the main thread, when the surface is removed from the - * draw list */ - virtual status_t ditch() { return NO_ERROR; } - - /** called with the state lock when the surface is removed from the - * current list */ - virtual void onRemoved() { }; - - /** always call base class first */ - virtual void dump(String8& result, char* scratch, size_t size) const; - - - enum { // flags for doTransaction() - eVisibleRegion = 0x00000002, - }; - - - inline const State& drawingState() const { return mDrawingState; } - inline const State& currentState() const { return mCurrentState; } - inline State& currentState() { return mCurrentState; } - - static int compareCurrentStateZ( - sp<LayerBase> const * layerA, - sp<LayerBase> const * layerB) { - return layerA[0]->currentState().z - layerB[0]->currentState().z; - } - - int32_t getOrientation() const { return mOrientation; } - int tx() const { return mLeft; } - int ty() const { return mTop; } - -protected: - const GraphicPlane& graphicPlane(int dpy) const; - GraphicPlane& graphicPlane(int dpy); - - void clearWithOpenGL(const Region& clip, GLclampf r, GLclampf g, - GLclampf b, GLclampf alpha) const; - void clearWithOpenGL(const Region& clip) const; - void drawWithOpenGL(const Region& clip, const Texture& texture) const; - - sp<SurfaceFlinger> mFlinger; - uint32_t mFlags; - - // cached during validateVisibility() - bool mNeedsFiltering; - int32_t mOrientation; - GLfloat mVertices[4][2]; - Rect mTransformedBounds; - int mLeft; - int mTop; - - // these are protected by an external lock - State mCurrentState; - State mDrawingState; - volatile int32_t mTransactionFlags; - - // don't change, don't need a lock - bool mPremultipliedAlpha; - String8 mName; - mutable bool mDebug; - - - // atomic - volatile int32_t mInvalidate; - - -protected: - virtual ~LayerBase(); - -private: - LayerBase(const LayerBase& rhs); -}; - - -// --------------------------------------------------------------------------- - -class LayerBaseClient : public LayerBase -{ -public: - class Surface; - - LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - virtual ~LayerBaseClient(); - - sp<Surface> getSurface(); - virtual sp<Surface> createSurface() const; - virtual sp<LayerBaseClient> getLayerBaseClient() const { - return const_cast<LayerBaseClient*>(this); } - virtual const char* getTypeId() const { return "LayerBaseClient"; } - - uint32_t getIdentity() const { return mIdentity; } - - class Surface : public BnSurface { - public: - int32_t getIdentity() const { return mIdentity; } - - protected: - Surface(const sp<SurfaceFlinger>& flinger, int identity, - const sp<LayerBaseClient>& owner); - virtual ~Surface(); - virtual status_t onTransact(uint32_t code, const Parcel& data, - Parcel* reply, uint32_t flags); - sp<LayerBaseClient> getOwner() const; - - private: - virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage); - virtual status_t setBufferCount(int bufferCount); - - virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); - virtual void postBuffer(ssize_t offset); - virtual void unregisterBuffers(); - virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, - int32_t format, int32_t orientation); - - protected: - friend class LayerBaseClient; - sp<SurfaceFlinger> mFlinger; - int32_t mIdentity; - wp<LayerBaseClient> mOwner; - }; - - friend class Surface; - -protected: - virtual void dump(String8& result, char* scratch, size_t size) const; - -private: - mutable Mutex mLock; - mutable wp<Surface> mClientSurface; - const wp<Client> mClientRef; - // only read - const uint32_t mIdentity; - static int32_t sIdentity; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_BASE_H diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp deleted file mode 100644 index 64a43c7..0000000 --- a/libs/surfaceflinger/LayerBlur.cpp +++ /dev/null @@ -1,249 +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. - */ - -#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 "clz.h" -#include "BlurFilter.h" -#include "LayerBlur.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" - -namespace android { -// --------------------------------------------------------------------------- - -LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBaseClient(flinger, display, client), mCacheDirty(true), - mRefreshCache(true), mCacheAge(0), mTextureName(-1U), - mWidthScale(1.0f), mHeightScale(1.0f), - mBlurFormat(GGL_PIXEL_FORMAT_RGB_565) -{ -} - -LayerBlur::~LayerBlur() -{ - if (mTextureName != -1U) { - glDeleteTextures(1, &mTextureName); - } -} - -void LayerBlur::setVisibleRegion(const Region& visibleRegion) -{ - LayerBaseClient::setVisibleRegion(visibleRegion); - if (visibleRegionScreen.isEmpty()) { - if (mTextureName != -1U) { - // We're not visible, free the texture up. - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &mTextureName); - mTextureName = -1U; - } - } -} - -uint32_t LayerBlur::doTransaction(uint32_t flags) -{ - // we're doing a transaction, refresh the cache! - if (!mFlinger->isFrozen()) { - mRefreshCache = true; - mCacheDirty = true; - flags |= eVisibleRegion; - this->contentDirty = true; - } - return LayerBase::doTransaction(flags); -} - -void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion) -{ - // this code-path must be as tight as possible, it's called each time - // the screen is composited. - if (UNLIKELY(!visibleRegionScreen.isEmpty())) { - // if anything visible below us is invalidated, the cache becomes dirty - if (!mCacheDirty && - !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) { - mCacheDirty = true; - } - if (mCacheDirty) { - if (!mFlinger->isFrozen()) { - // update everything below us that is visible - outDirtyRegion.orSelf(visibleRegionScreen); - nsecs_t now = systemTime(); - if ((now - mCacheAge) >= ms2ns(500)) { - mCacheAge = now; - mRefreshCache = true; - mCacheDirty = false; - } else { - if (!mAutoRefreshPending) { - mFlinger->postMessageAsync( - new MessageBase(MessageQueue::INVALIDATE), - ms2ns(500)); - mAutoRefreshPending = true; - } - } - } - } - } - LayerBase::unlockPageFlip(planeTransform, outDirtyRegion); -} - -void LayerBlur::onDraw(const Region& clip) const -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t fbHeight = hw.getHeight(); - int x = mTransformedBounds.left; - int y = mTransformedBounds.top; - int w = mTransformedBounds.width(); - int h = mTransformedBounds.height(); - GLint X = x; - GLint Y = fbHeight - (y + h); - if (X < 0) { - w += X; - X = 0; - } - if (Y < 0) { - h += Y; - Y = 0; - } - if (w<0 || h<0) { - // we're outside of the framebuffer - return; - } - - if (mTextureName == -1U) { - // create the texture name the first time - // can't do that in the ctor, because it runs in another thread. - glGenTextures(1, &mTextureName); - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat); - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType); - if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) { - mReadFormat = GL_RGBA; - mReadType = GL_UNSIGNED_BYTE; - mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888; - } - } - - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - if (it != end) { -#if defined(GL_OES_texture_external) - if (GLExtensions::getInstance().haveTextureExternal()) { - glDisable(GL_TEXTURE_EXTERNAL_OES); - } -#endif - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, mTextureName); - - if (mRefreshCache) { - mRefreshCache = false; - mAutoRefreshPending = false; - - int32_t pixelSize = 4; - int32_t s = w; - if (mReadType == GL_UNSIGNED_SHORT_5_6_5) { - // allocate enough memory for 4-bytes (2 pixels) aligned data - s = (w + 1) & ~1; - pixelSize = 2; - } - - uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize); - - // This reads the frame-buffer, so a h/w GL would have to - // finish() its rendering first. we don't want to do that - // too often. Read data is 4-bytes aligned. - glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels); - - // blur that texture. - GGLSurface bl; - bl.version = sizeof(GGLSurface); - bl.width = w; - bl.height = h; - bl.stride = s; - bl.format = mBlurFormat; - bl.data = (GGLubyte*)pixels; - blurFilter(&bl, 8, 2); - - if (GLExtensions::getInstance().haveNpot()) { - glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0, - mReadFormat, mReadType, pixels); - mWidthScale = 1.0f / w; - mHeightScale =-1.0f / h; - mYOffset = 0; - } else { - GLuint tw = 1 << (31 - clz(w)); - GLuint th = 1 << (31 - clz(h)); - if (tw < GLuint(w)) tw <<= 1; - if (th < GLuint(h)) th <<= 1; - glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0, - mReadFormat, mReadType, NULL); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, - mReadFormat, mReadType, pixels); - mWidthScale = 1.0f / tw; - mHeightScale =-1.0f / th; - mYOffset = th-h; - } - - free((void*)pixels); - } - - const State& s = drawingState(); - if (UNLIKELY(s.alpha < 0xFF)) { - const GLfloat alpha = s.alpha * (1.0f/255.0f); - glColor4f(0, 0, 0, alpha); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - } else { - glDisable(GL_BLEND); - } - - if (mFlags & DisplayHardware::SLOW_CONFIG) { - glDisable(GL_DITHER); - } else { - glEnable(GL_DITHER); - } - - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef(mWidthScale, mHeightScale, 1); - glTranslatef(-x, mYOffset - y, 0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, mVertices); - glTexCoordPointer(2, GL_FLOAT, 0, mVertices); - while (it != end) { - const Rect& r = *it++; - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h deleted file mode 100644 index 4c9ec64..0000000 --- a/libs/surfaceflinger/LayerBlur.h +++ /dev/null @@ -1,65 +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. - */ - -#ifndef ANDROID_LAYER_BLUR_H -#define ANDROID_LAYER_BLUR_H - -#include <stdint.h> -#include <sys/types.h> - -#include <ui/Region.h> - -#include "LayerBase.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class LayerBlur : public LayerBaseClient -{ -public: - LayerBlur(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - virtual ~LayerBlur(); - - virtual void onDraw(const Region& clip) const; - virtual bool needsBlending() const { return true; } - virtual bool isSecure() const { return false; } - virtual const char* getTypeId() const { return "LayerBlur"; } - - virtual uint32_t doTransaction(uint32_t flags); - virtual void setVisibleRegion(const Region& visibleRegion); - virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); - -private: - bool mCacheDirty; - mutable bool mRefreshCache; - mutable bool mAutoRefreshPending; - nsecs_t mCacheAge; - mutable GLuint mTextureName; - mutable GLfloat mWidthScale; - mutable GLfloat mHeightScale; - mutable GLfloat mYOffset; - mutable GLint mReadFormat; - mutable GLint mReadType; - mutable uint32_t mBlurFormat; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_BLUR_H diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp deleted file mode 100644 index 5f83636..0000000 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ /dev/null @@ -1,682 +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. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <math.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/Log.h> -#include <utils/StopWatch.h> - -#include <ui/GraphicBuffer.h> -#include <ui/PixelFormat.h> -#include <ui/FramebufferNativeWindow.h> -#include <ui/Rect.h> -#include <ui/Region.h> - -#include <hardware/copybit.h> - -#include "LayerBuffer.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" - -namespace android { - -// --------------------------------------------------------------------------- - -gralloc_module_t const* LayerBuffer::sGrallocModule = 0; - -// --------------------------------------------------------------------------- - -LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBaseClient(flinger, display, client), - mNeedsBlending(false), mBlitEngine(0) -{ -} - -LayerBuffer::~LayerBuffer() -{ - if (mBlitEngine) { - copybit_close(mBlitEngine); - } -} - -void LayerBuffer::onFirstRef() -{ - LayerBaseClient::onFirstRef(); - mSurface = new SurfaceLayerBuffer(mFlinger, this); - - hw_module_t const* module = (hw_module_t const*)sGrallocModule; - if (!module) { - // NOTE: technically there is a race here, but it shouldn't - // cause any problem since hw_get_module() always returns - // the same value. - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { - sGrallocModule = (gralloc_module_t const *)module; - } - } - - if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { - copybit_open(module, &mBlitEngine); - } -} - -sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const -{ - return mSurface; -} - -status_t LayerBuffer::ditch() -{ - mSurface.clear(); - return NO_ERROR; -} - -bool LayerBuffer::needsBlending() const { - return mNeedsBlending; -} - -void LayerBuffer::setNeedsBlending(bool blending) { - mNeedsBlending = blending; -} - -void LayerBuffer::postBuffer(ssize_t offset) -{ - sp<Source> source(getSource()); - if (source != 0) - source->postBuffer(offset); -} - -void LayerBuffer::unregisterBuffers() -{ - sp<Source> source(clearSource()); - if (source != 0) - source->unregisterBuffers(); -} - -uint32_t LayerBuffer::doTransaction(uint32_t flags) -{ - sp<Source> source(getSource()); - if (source != 0) - source->onTransaction(flags); - uint32_t res = LayerBase::doTransaction(flags); - // we always want filtering for these surfaces - mNeedsFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG); - return res; -} - -void LayerBuffer::unlockPageFlip(const Transform& planeTransform, - Region& outDirtyRegion) -{ - // this code-path must be as tight as possible, it's called each time - // the screen is composited. - sp<Source> source(getSource()); - if (source != 0) - source->onVisibilityResolved(planeTransform); - LayerBase::unlockPageFlip(planeTransform, outDirtyRegion); -} - -void LayerBuffer::onDraw(const Region& clip) const -{ - sp<Source> source(getSource()); - if (LIKELY(source != 0)) { - source->onDraw(clip); - } else { - clearWithOpenGL(clip); - } -} - -void LayerBuffer::serverDestroy() -{ - sp<Source> source(clearSource()); - if (source != 0) { - source->destroy(); - } -} - -/** - * This creates a "buffer" source for this surface - */ -status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers) -{ - Mutex::Autolock _l(mLock); - if (mSource != 0) - return INVALID_OPERATION; - - sp<BufferSource> source = new BufferSource(*this, buffers); - - status_t result = source->getStatus(); - if (result == NO_ERROR) { - mSource = source; - } - return result; -} - -/** - * This creates an "overlay" source for this surface - */ -sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f, - int32_t orientation) -{ - sp<OverlayRef> result; - Mutex::Autolock _l(mLock); - if (mSource != 0) - return result; - - sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f, orientation); - if (result != 0) { - mSource = source; - } - return result; -} - -sp<LayerBuffer::Source> LayerBuffer::getSource() const { - Mutex::Autolock _l(mLock); - return mSource; -} - -sp<LayerBuffer::Source> LayerBuffer::clearSource() { - sp<Source> source; - Mutex::Autolock _l(mLock); - source = mSource; - mSource.clear(); - return source; -} - -// ============================================================================ -// LayerBuffer::SurfaceLayerBuffer -// ============================================================================ - -LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer( - const sp<SurfaceFlinger>& flinger, const sp<LayerBuffer>& owner) - : LayerBaseClient::Surface(flinger, owner->getIdentity(), owner) -{ -} - -LayerBuffer::SurfaceLayerBuffer::~SurfaceLayerBuffer() -{ - unregisterBuffers(); -} - -status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers( - const ISurface::BufferHeap& buffers) -{ - sp<LayerBuffer> owner(getOwner()); - if (owner != 0) - return owner->registerBuffers(buffers); - return NO_INIT; -} - -void LayerBuffer::SurfaceLayerBuffer::postBuffer(ssize_t offset) -{ - sp<LayerBuffer> owner(getOwner()); - if (owner != 0) - owner->postBuffer(offset); -} - -void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers() -{ - sp<LayerBuffer> owner(getOwner()); - if (owner != 0) - owner->unregisterBuffers(); -} - -sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay( - uint32_t w, uint32_t h, int32_t format, int32_t orientation) { - sp<OverlayRef> result; - sp<LayerBuffer> owner(getOwner()); - if (owner != 0) - result = owner->createOverlay(w, h, format, orientation); - return result; -} - -// ============================================================================ -// LayerBuffer::Buffer -// ============================================================================ - -LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, - ssize_t offset, size_t bufferSize) - : mBufferHeap(buffers), mSupportsCopybit(false) -{ - NativeBuffer& src(mNativeBuffer); - src.crop.l = 0; - src.crop.t = 0; - src.crop.r = buffers.w; - src.crop.b = buffers.h; - - src.img.w = buffers.hor_stride ?: buffers.w; - src.img.h = buffers.ver_stride ?: buffers.h; - src.img.format = buffers.format; - src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); - src.img.handle = 0; - - gralloc_module_t const * module = LayerBuffer::getGrallocModule(); - if (module && module->perform) { - int err = module->perform(module, - GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER, - buffers.heap->heapID(), bufferSize, - offset, buffers.heap->base(), - &src.img.handle); - - // we can fail here is the passed buffer is purely software - mSupportsCopybit = (err == NO_ERROR); - } - } - -LayerBuffer::Buffer::~Buffer() -{ - NativeBuffer& src(mNativeBuffer); - if (src.img.handle) { - native_handle_delete(src.img.handle); - } -} - -// ============================================================================ -// LayerBuffer::Source -// LayerBuffer::BufferSource -// LayerBuffer::OverlaySource -// ============================================================================ - -LayerBuffer::Source::Source(LayerBuffer& layer) - : mLayer(layer) -{ -} -LayerBuffer::Source::~Source() { -} -void LayerBuffer::Source::onDraw(const Region& clip) const { -} -void LayerBuffer::Source::onTransaction(uint32_t flags) { -} -void LayerBuffer::Source::onVisibilityResolved( - const Transform& planeTransform) { -} -void LayerBuffer::Source::postBuffer(ssize_t offset) { -} -void LayerBuffer::Source::unregisterBuffers() { -} - -// --------------------------------------------------------------------------- - -LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, - const ISurface::BufferHeap& buffers) - : Source(layer), mStatus(NO_ERROR), mBufferSize(0) -{ - if (buffers.heap == NULL) { - // this is allowed, but in this case, it is illegal to receive - // postBuffer(). The surface just erases the framebuffer with - // fully transparent pixels. - mBufferHeap = buffers; - mLayer.setNeedsBlending(false); - return; - } - - status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT; - if (err != NO_ERROR) { - LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err)); - mStatus = err; - return; - } - - PixelFormatInfo info; - err = getPixelFormatInfo(buffers.format, &info); - if (err != NO_ERROR) { - LOGE("LayerBuffer::BufferSource: invalid format %d (%s)", - buffers.format, strerror(err)); - mStatus = err; - return; - } - - if (buffers.hor_stride<0 || buffers.ver_stride<0) { - LOGE("LayerBuffer::BufferSource: invalid parameters " - "(w=%d, h=%d, xs=%d, ys=%d)", - buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride); - mStatus = BAD_VALUE; - return; - } - - mBufferHeap = buffers; - mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0); - mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride; - mLayer.forceVisibilityTransaction(); -} - -LayerBuffer::BufferSource::~BufferSource() -{ - class MessageDestroyTexture : public MessageBase { - SurfaceFlinger* flinger; - GLuint name; - public: - MessageDestroyTexture( - SurfaceFlinger* flinger, GLuint name) - : flinger(flinger), name(name) { } - virtual bool handler() { - glDeleteTextures(1, &name); - return true; - } - }; - - if (mTexture.name != -1U) { - // GL textures can only be destroyed from the GL thread - getFlinger()->mEventQueue.postMessage( - new MessageDestroyTexture(getFlinger(), mTexture.name) ); - } - if (mTexture.image != EGL_NO_IMAGE_KHR) { - EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay()); - eglDestroyImageKHR(dpy, mTexture.image); - } -} - -void LayerBuffer::BufferSource::postBuffer(ssize_t offset) -{ - ISurface::BufferHeap buffers; - { // scope for the lock - Mutex::Autolock _l(mBufferSourceLock); - buffers = mBufferHeap; - if (buffers.heap != 0) { - const size_t memorySize = buffers.heap->getSize(); - if ((size_t(offset) + mBufferSize) > memorySize) { - LOGE("LayerBuffer::BufferSource::postBuffer() " - "invalid buffer (offset=%d, size=%d, heap-size=%d", - int(offset), int(mBufferSize), int(memorySize)); - return; - } - } - } - - sp<Buffer> buffer; - if (buffers.heap != 0) { - buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize); - if (buffer->getStatus() != NO_ERROR) - buffer.clear(); - setBuffer(buffer); - mLayer.invalidate(); - } -} - -void LayerBuffer::BufferSource::unregisterBuffers() -{ - Mutex::Autolock _l(mBufferSourceLock); - mBufferHeap.heap.clear(); - mBuffer.clear(); - mLayer.invalidate(); -} - -sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const -{ - Mutex::Autolock _l(mBufferSourceLock); - return mBuffer; -} - -void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer) -{ - Mutex::Autolock _l(mBufferSourceLock); - mBuffer = buffer; -} - -void LayerBuffer::BufferSource::onDraw(const Region& clip) const -{ - sp<Buffer> ourBuffer(getBuffer()); - if (UNLIKELY(ourBuffer == 0)) { - // nothing to do, we don't have a buffer - mLayer.clearWithOpenGL(clip); - return; - } - - status_t err = NO_ERROR; - NativeBuffer src(ourBuffer->getBuffer()); - const Rect transformedBounds(mLayer.getTransformedBounds()); - -#if defined(EGL_ANDROID_image_native_buffer) - if (GLExtensions::getInstance().haveDirectTexture()) { - err = INVALID_OPERATION; - if (ourBuffer->supportsCopybit()) { - copybit_device_t* copybit = mLayer.mBlitEngine; - if (copybit && err != NO_ERROR) { - // create our EGLImageKHR the first time - err = initTempBuffer(); - if (err == NO_ERROR) { - // NOTE: Assume the buffer is allocated with the proper USAGE flags - const NativeBuffer& dst(mTempBuffer); - region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - err = copybit->stretch(copybit, &dst.img, &src.img, - &dst.crop, &src.crop, &clip); - if (err != NO_ERROR) { - clearTempBufferImage(); - } - } - } - } - } -#endif - else { - err = INVALID_OPERATION; - } - - if (err != NO_ERROR) { - // slower fallback - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.crop.r; - t.height = src.crop.b; - t.stride = src.img.w; - t.vstride= src.img.h; - t.format = src.img.format; - t.data = (GGLubyte*)src.img.base; - const Region dirty(Rect(t.width, t.height)); - mTextureManager.loadTexture(&mTexture, dirty, t); - } - - mTexture.transform = mBufferHeap.transform; - mLayer.drawWithOpenGL(clip, mTexture); -} - -status_t LayerBuffer::BufferSource::initTempBuffer() const -{ - // figure out the size we need now - const ISurface::BufferHeap& buffers(mBufferHeap); - uint32_t w = mLayer.mTransformedBounds.width(); - uint32_t h = mLayer.mTransformedBounds.height(); - if (buffers.w * h != buffers.h * w) { - int t = w; w = h; h = t; - } - - // we're in the copybit case, so make sure we can handle this blit - // we don't have to keep the aspect ratio here - copybit_device_t* copybit = mLayer.mBlitEngine; - const int down = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); - const int up = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); - if (buffers.w > w*down) w = buffers.w / down; - else if (w > buffers.w*up) w = buffers.w*up; - if (buffers.h > h*down) h = buffers.h / down; - else if (h > buffers.h*up) h = buffers.h*up; - - if (mTexture.image != EGL_NO_IMAGE_KHR) { - // we have an EGLImage, make sure the needed size didn't change - if (w!=mTexture.width || h!= mTexture.height) { - // delete the EGLImage and texture - clearTempBufferImage(); - } else { - // we're good, we have an EGLImageKHR and it's (still) the - // right size - return NO_ERROR; - } - } - - // figure out if we need linear filtering - if (buffers.w * h == buffers.h * w) { - // same pixel area, don't use filtering - mLayer.mNeedsFiltering = false; - } - - // Allocate a temporary buffer and create the corresponding EGLImageKHR - // once the EGLImage has been created we don't need the - // graphic buffer reference anymore. - sp<GraphicBuffer> buffer = new GraphicBuffer( - w, h, HAL_PIXEL_FORMAT_RGB_565, - GraphicBuffer::USAGE_HW_TEXTURE | - GraphicBuffer::USAGE_HW_2D); - - status_t err = buffer->initCheck(); - if (err == NO_ERROR) { - NativeBuffer& dst(mTempBuffer); - dst.img.w = buffer->getStride(); - dst.img.h = h; - dst.img.format = buffer->getPixelFormat(); - dst.img.handle = (native_handle_t *)buffer->handle; - dst.img.base = 0; - dst.crop.l = 0; - dst.crop.t = 0; - dst.crop.r = w; - dst.crop.b = h; - - EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay()); - err = mTextureManager.initEglImage(&mTexture, dpy, buffer); - } - - return err; -} - -void LayerBuffer::BufferSource::clearTempBufferImage() const -{ - // delete the image - EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay()); - eglDestroyImageKHR(dpy, mTexture.image); - - // and the associated texture (recreate a name) - glDeleteTextures(1, &mTexture.name); - Texture defaultTexture; - mTexture = defaultTexture; -} - -// --------------------------------------------------------------------------- - -LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer, - sp<OverlayRef>* overlayRef, - uint32_t w, uint32_t h, int32_t format, int32_t orientation) - : Source(layer), mVisibilityChanged(false), - mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation) -{ - overlay_control_device_t* overlay_dev = getFlinger()->getOverlayEngine(); - if (overlay_dev == NULL) { - // overlays not supported - return; - } - - mOverlayDevice = overlay_dev; - overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format); - if (overlay == NULL) { - // couldn't create the overlay (no memory? no more overlays?) - return; - } - - // enable dithering... - overlay_dev->setParameter(overlay_dev, overlay, - OVERLAY_DITHER, OVERLAY_ENABLE); - - mOverlay = overlay; - mWidth = overlay->w; - mHeight = overlay->h; - mFormat = overlay->format; - mWidthStride = overlay->w_stride; - mHeightStride = overlay->h_stride; - mInitialized = false; - - mOverlayHandle = overlay->getHandleRef(overlay); - - sp<OverlayChannel> channel = new OverlayChannel( &layer ); - - *overlayRef = new OverlayRef(mOverlayHandle, channel, - mWidth, mHeight, mFormat, mWidthStride, mHeightStride); - getFlinger()->signalEvent(); -} - -LayerBuffer::OverlaySource::~OverlaySource() -{ - if (mOverlay && mOverlayDevice) { - overlay_control_device_t* overlay_dev = mOverlayDevice; - overlay_dev->destroyOverlay(overlay_dev, mOverlay); - } -} - -void LayerBuffer::OverlaySource::onDraw(const Region& clip) const -{ - // this would be where the color-key would be set, should we need it. - GLclampf red = 0; - GLclampf green = 0; - GLclampf blue = 0; - mLayer.clearWithOpenGL(clip, red, green, blue, 0); -} - -void LayerBuffer::OverlaySource::onTransaction(uint32_t flags) -{ - const Layer::State& front(mLayer.drawingState()); - const Layer::State& temp(mLayer.currentState()); - if (temp.sequence != front.sequence) { - mVisibilityChanged = true; - } -} - -void LayerBuffer::OverlaySource::onVisibilityResolved( - const Transform& planeTransform) -{ - // this code-path must be as tight as possible, it's called each time - // the screen is composited. - if (UNLIKELY(mOverlay != 0)) { - if (mVisibilityChanged || !mInitialized) { - mVisibilityChanged = false; - mInitialized = true; - const Rect bounds(mLayer.getTransformedBounds()); - int x = bounds.left; - int y = bounds.top; - int w = bounds.width(); - int h = bounds.height(); - - // we need a lock here to protect "destroy" - Mutex::Autolock _l(mOverlaySourceLock); - if (mOverlay) { - overlay_control_device_t* overlay_dev = mOverlayDevice; - overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h); - // we need to combine the layer orientation and the - // user-requested orientation. - Transform finalTransform = Transform(mOrientation) * - Transform(mLayer.getOrientation()); - overlay_dev->setParameter(overlay_dev, mOverlay, - OVERLAY_TRANSFORM, finalTransform.getOrientation()); - overlay_dev->commit(overlay_dev, mOverlay); - } - } - } -} - -void LayerBuffer::OverlaySource::destroy() -{ - // we need a lock here to protect "onVisibilityResolved" - Mutex::Autolock _l(mOverlaySourceLock); - if (mOverlay && mOverlayDevice) { - overlay_control_device_t* overlay_dev = mOverlayDevice; - overlay_dev->destroyOverlay(overlay_dev, mOverlay); - mOverlay = 0; - } -} - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h deleted file mode 100644 index 1c0bf83..0000000 --- a/libs/surfaceflinger/LayerBuffer.h +++ /dev/null @@ -1,220 +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. - */ - -#ifndef ANDROID_LAYER_BUFFER_H -#define ANDROID_LAYER_BUFFER_H - -#include <stdint.h> -#include <sys/types.h> - -#include "LayerBase.h" -#include "TextureManager.h" - -struct copybit_device_t; - -namespace android { - -// --------------------------------------------------------------------------- - -class Buffer; -class Region; -class OverlayRef; - -// --------------------------------------------------------------------------- - -class LayerBuffer : public LayerBaseClient -{ - class Source : public LightRefBase<Source> { - public: - Source(LayerBuffer& layer); - virtual ~Source(); - virtual void onDraw(const Region& clip) const; - virtual void onTransaction(uint32_t flags); - virtual void onVisibilityResolved(const Transform& planeTransform); - virtual void postBuffer(ssize_t offset); - virtual void unregisterBuffers(); - virtual void destroy() { } - SurfaceFlinger* getFlinger() const { return mLayer.mFlinger.get(); } - protected: - LayerBuffer& mLayer; - }; - -public: - LayerBuffer(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - virtual ~LayerBuffer(); - - virtual void onFirstRef(); - virtual bool needsBlending() const; - virtual const char* getTypeId() const { return "LayerBuffer"; } - - virtual sp<LayerBaseClient::Surface> createSurface() const; - virtual status_t ditch(); - virtual void onDraw(const Region& clip) const; - virtual uint32_t doTransaction(uint32_t flags); - virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); - - status_t registerBuffers(const ISurface::BufferHeap& buffers); - void postBuffer(ssize_t offset); - void unregisterBuffers(); - sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format, - int32_t orientation); - - sp<Source> getSource() const; - sp<Source> clearSource(); - void setNeedsBlending(bool blending); - Rect getTransformedBounds() const { - return mTransformedBounds; - } - - void serverDestroy(); - -private: - struct NativeBuffer { - copybit_image_t img; - copybit_rect_t crop; - }; - - static gralloc_module_t const* sGrallocModule; - static gralloc_module_t const* getGrallocModule() { - return sGrallocModule; - } - - class Buffer : public LightRefBase<Buffer> { - public: - Buffer(const ISurface::BufferHeap& buffers, - ssize_t offset, size_t bufferSize); - inline bool supportsCopybit() const { - return mSupportsCopybit; - } - inline status_t getStatus() const { - return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT; - } - inline const NativeBuffer& getBuffer() const { - return mNativeBuffer; - } - protected: - friend class LightRefBase<Buffer>; - Buffer& operator = (const Buffer& rhs); - Buffer(const Buffer& rhs); - ~Buffer(); - private: - ISurface::BufferHeap mBufferHeap; - NativeBuffer mNativeBuffer; - bool mSupportsCopybit; - }; - - class BufferSource : public Source { - public: - BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers); - virtual ~BufferSource(); - - status_t getStatus() const { return mStatus; } - sp<Buffer> getBuffer() const; - void setBuffer(const sp<Buffer>& buffer); - - virtual void onDraw(const Region& clip) const; - virtual void postBuffer(ssize_t offset); - virtual void unregisterBuffers(); - virtual void destroy() { } - private: - status_t initTempBuffer() const; - void clearTempBufferImage() const; - mutable Mutex mBufferSourceLock; - sp<Buffer> mBuffer; - status_t mStatus; - ISurface::BufferHeap mBufferHeap; - size_t mBufferSize; - mutable Texture mTexture; - mutable NativeBuffer mTempBuffer; - mutable TextureManager mTextureManager; - }; - - class OverlaySource : public Source { - public: - OverlaySource(LayerBuffer& layer, - sp<OverlayRef>* overlayRef, - uint32_t w, uint32_t h, int32_t format, int32_t orientation); - virtual ~OverlaySource(); - virtual void onDraw(const Region& clip) const; - virtual void onTransaction(uint32_t flags); - virtual void onVisibilityResolved(const Transform& planeTransform); - virtual void destroy(); - private: - - class OverlayChannel : public BnOverlay { - wp<LayerBuffer> mLayer; - virtual void destroy() { - sp<LayerBuffer> layer(mLayer.promote()); - if (layer != 0) { - layer->serverDestroy(); - } - } - public: - OverlayChannel(const sp<LayerBuffer>& layer) - : mLayer(layer) { - } - }; - - friend class OverlayChannel; - bool mVisibilityChanged; - - overlay_t* mOverlay; - overlay_handle_t mOverlayHandle; - overlay_control_device_t* mOverlayDevice; - uint32_t mWidth; - uint32_t mHeight; - int32_t mFormat; - int32_t mWidthStride; - int32_t mHeightStride; - int32_t mOrientation; - mutable Mutex mOverlaySourceLock; - bool mInitialized; - }; - - - class SurfaceLayerBuffer : public LayerBaseClient::Surface - { - public: - SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger, - const sp<LayerBuffer>& owner); - virtual ~SurfaceLayerBuffer(); - - virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); - virtual void postBuffer(ssize_t offset); - virtual void unregisterBuffers(); - - virtual sp<OverlayRef> createOverlay( - uint32_t w, uint32_t h, int32_t format, int32_t orientation); - private: - sp<LayerBuffer> getOwner() const { - return static_cast<LayerBuffer*>(Surface::getOwner().get()); - } - }; - - mutable Mutex mLock; - sp<Source> mSource; - sp<Surface> mSurface; - bool mInvalidate; - bool mNeedsBlending; - copybit_device_t* mBlitEngine; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_BUFFER_H diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp deleted file mode 100644 index a1f339e..0000000 --- a/libs/surfaceflinger/LayerDim.cpp +++ /dev/null @@ -1,103 +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. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/Log.h> - -#include <ui/GraphicBuffer.h> - -#include "LayerDim.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" - -namespace android { -// --------------------------------------------------------------------------- - -bool LayerDim::sUseTexture; -GLuint LayerDim::sTexId; -EGLImageKHR LayerDim::sImage; -int32_t LayerDim::sWidth; -int32_t LayerDim::sHeight; - -// --------------------------------------------------------------------------- - -LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBaseClient(flinger, display, client) -{ -} - -void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) -{ - sTexId = -1; - sImage = EGL_NO_IMAGE_KHR; - sWidth = w; - sHeight = h; - sUseTexture = false; -} - -LayerDim::~LayerDim() -{ -} - -void LayerDim::onDraw(const Region& clip) const -{ - const State& s(drawingState()); - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - if (s.alpha>0 && (it != end)) { - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const GLfloat alpha = s.alpha/255.0f; - const uint32_t fbHeight = hw.getHeight(); - glDisable(GL_DITHER); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, 0, alpha); - -#if defined(GL_OES_texture_external) - if (GLExtensions::getInstance().haveTextureExternal()) { - glDisable(GL_TEXTURE_EXTERNAL_OES); - } -#endif - glDisable(GL_TEXTURE_2D); - - GLshort w = sWidth; - GLshort h = sHeight; - const GLshort vertices[4][2] = { - { 0, 0 }, - { 0, h }, - { w, h }, - { w, 0 } - }; - glVertexPointer(2, GL_SHORT, 0, vertices); - - while (it != end) { - const Rect& r = *it++; - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h deleted file mode 100644 index f032314..0000000 --- a/libs/surfaceflinger/LayerDim.h +++ /dev/null @@ -1,56 +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. - */ - -#ifndef ANDROID_LAYER_DIM_H -#define ANDROID_LAYER_DIM_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include "LayerBase.h" - -// --------------------------------------------------------------------------- - -namespace android { - -class LayerDim : public LayerBaseClient -{ - static bool sUseTexture; - static GLuint sTexId; - static EGLImageKHR sImage; - static int32_t sWidth; - static int32_t sHeight; -public: - LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - virtual ~LayerDim(); - - virtual void onDraw(const Region& clip) const; - virtual bool needsBlending() const { return true; } - virtual bool isSecure() const { return false; } - virtual const char* getTypeId() const { return "LayerDim"; } - - static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h); -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_DIM_H diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/libs/surfaceflinger/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/libs/surfaceflinger/MessageQueue.cpp b/libs/surfaceflinger/MessageQueue.cpp deleted file mode 100644 index d668e88..0000000 --- a/libs/surfaceflinger/MessageQueue.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -#include <stdint.h> -#include <errno.h> -#include <sys/types.h> - -#include <utils/threads.h> -#include <utils/Timers.h> -#include <utils/Log.h> -#include <binder/IPCThreadState.h> - -#include "MessageQueue.h" - -namespace android { - -// --------------------------------------------------------------------------- - -void MessageList::insert(const sp<MessageBase>& node) -{ - LIST::iterator cur(mList.begin()); - LIST::iterator end(mList.end()); - while (cur != end) { - if (*node < **cur) { - mList.insert(cur, node); - return; - } - ++cur; - } - mList.insert(++end, node); -} - -void MessageList::remove(MessageList::LIST::iterator pos) -{ - mList.erase(pos); -} - -// --------------------------------------------------------------------------- - -MessageQueue::MessageQueue() - : mInvalidate(false) -{ - mInvalidateMessage = new MessageBase(INVALIDATE); -} - -MessageQueue::~MessageQueue() -{ -} - -sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout) -{ - sp<MessageBase> result; - - bool again; - do { - const nsecs_t timeoutTime = systemTime() + timeout; - while (true) { - Mutex::Autolock _l(mLock); - nsecs_t now = systemTime(); - nsecs_t nextEventTime = -1; - - // invalidate messages are always handled first - if (mInvalidate) { - mInvalidate = false; - mInvalidateMessage->when = now; - result = mInvalidateMessage; - break; - } - - LIST::iterator cur(mMessages.begin()); - if (cur != mMessages.end()) { - result = *cur; - } - - if (result != 0) { - if (result->when <= now) { - // there is a message to deliver - mMessages.remove(cur); - break; - } - if (timeout>=0 && timeoutTime < now) { - // we timed-out, return a NULL message - result = 0; - break; - } - nextEventTime = result->when; - result = 0; - } - - if (timeout >= 0 && nextEventTime > 0) { - if (nextEventTime > timeoutTime) { - nextEventTime = timeoutTime; - } - } - - if (nextEventTime >= 0) { - //LOGD("nextEventTime = %lld ms", nextEventTime); - if (nextEventTime > 0) { - // we're about to wait, flush the binder command buffer - IPCThreadState::self()->flushCommands(); - const nsecs_t reltime = nextEventTime - systemTime(); - if (reltime > 0) { - mCondition.waitRelative(mLock, reltime); - } - } - } else { - //LOGD("going to wait"); - // we're about to wait, flush the binder command buffer - IPCThreadState::self()->flushCommands(); - mCondition.wait(mLock); - } - } - // here we're not holding the lock anymore - - if (result == 0) - break; - - again = result->handler(); - if (again) { - // the message has been processed. release our reference to it - // without holding the lock. - result->notify(); - result = 0; - } - - } while (again); - - return result; -} - -status_t MessageQueue::postMessage( - const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags) -{ - return queueMessage(message, relTime, flags); -} - -status_t MessageQueue::invalidate() { - Mutex::Autolock _l(mLock); - mInvalidate = true; - mCondition.signal(); - return NO_ERROR; -} - -status_t MessageQueue::queueMessage( - const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags) -{ - Mutex::Autolock _l(mLock); - message->when = systemTime() + relTime; - mMessages.insert(message); - - //LOGD("MessageQueue::queueMessage time = %lld ms", message->when); - //dumpLocked(message); - - mCondition.signal(); - return NO_ERROR; -} - -void MessageQueue::dump(const sp<MessageBase>& message) -{ - Mutex::Autolock _l(mLock); - dumpLocked(message); -} - -void MessageQueue::dumpLocked(const sp<MessageBase>& message) -{ - LIST::const_iterator cur(mMessages.begin()); - LIST::const_iterator end(mMessages.end()); - int c = 0; - while (cur != end) { - const char tick = (*cur == message) ? '>' : ' '; - LOGD("%c %d: msg{.what=%08x, when=%lld}", - tick, c, (*cur)->what, (*cur)->when); - ++cur; - c++; - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/MessageQueue.h b/libs/surfaceflinger/MessageQueue.h deleted file mode 100644 index 890f809..0000000 --- a/libs/surfaceflinger/MessageQueue.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -#ifndef ANDROID_MESSAGE_QUEUE_H -#define ANDROID_MESSAGE_QUEUE_H - -#include <stdint.h> -#include <errno.h> -#include <sys/types.h> - -#include <utils/threads.h> -#include <utils/Timers.h> -#include <utils/List.h> - -#include "Barrier.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class MessageBase; - -class MessageList -{ - List< sp<MessageBase> > mList; - typedef List< sp<MessageBase> > LIST; -public: - inline LIST::iterator begin() { return mList.begin(); } - inline LIST::const_iterator begin() const { return mList.begin(); } - inline LIST::iterator end() { return mList.end(); } - inline LIST::const_iterator end() const { return mList.end(); } - inline bool isEmpty() const { return mList.empty(); } - void insert(const sp<MessageBase>& node); - void remove(LIST::iterator pos); -}; - -// ============================================================================ - -class MessageBase : - public LightRefBase<MessageBase> -{ -public: - nsecs_t when; - uint32_t what; - int32_t arg0; - - MessageBase() : when(0), what(0), arg0(0) { } - MessageBase(uint32_t what, int32_t arg0=0) - : when(0), what(what), arg0(arg0) { } - - // return true if message has a handler - virtual bool handler() { return false; } - - // waits for the handler to be processed - void wait() const { barrier.wait(); } - - // releases all waiters. this is done automatically if - // handler returns true - void notify() const { barrier.open(); } - -protected: - virtual ~MessageBase() { } - -private: - mutable Barrier barrier; - friend class LightRefBase<MessageBase>; -}; - -inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) { - return lhs.when < rhs.when; -} - -// --------------------------------------------------------------------------- - -class MessageQueue -{ - typedef List< sp<MessageBase> > LIST; -public: - - MessageQueue(); - ~MessageQueue(); - - // pre-defined messages - enum { - INVALIDATE = '_upd' - }; - - sp<MessageBase> waitMessage(nsecs_t timeout = -1); - - status_t postMessage(const sp<MessageBase>& message, - nsecs_t reltime=0, uint32_t flags = 0); - - status_t invalidate(); - - void dump(const sp<MessageBase>& message); - -private: - status_t queueMessage(const sp<MessageBase>& message, - nsecs_t reltime, uint32_t flags); - void dumpLocked(const sp<MessageBase>& message); - - Mutex mLock; - Condition mCondition; - MessageList mMessages; - bool mInvalidate; - sp<MessageBase> mInvalidateMessage; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif /* ANDROID_MESSAGE_QUEUE_H */ diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp deleted file mode 100644 index 68e8f19..0000000 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ /dev/null @@ -1,1909 +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. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <math.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> - -#include <cutils/log.h> -#include <cutils/properties.h> - -#include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> -#include <binder/MemoryHeapBase.h> - -#include <utils/String8.h> -#include <utils/String16.h> -#include <utils/StopWatch.h> - -#include <ui/GraphicBufferAllocator.h> -#include <ui/PixelFormat.h> - -#include <pixelflinger/pixelflinger.h> -#include <GLES/gl.h> - -#include "clz.h" -#include "GLExtensions.h" -#include "Layer.h" -#include "LayerBlur.h" -#include "LayerBuffer.h" -#include "LayerDim.h" -#include "SurfaceFlinger.h" - -#include "DisplayHardware/DisplayHardware.h" - -/* ideally AID_GRAPHICS would be in a semi-public header - * or there would be a way to map a user/group name to its id - */ -#ifndef AID_GRAPHICS -#define AID_GRAPHICS 1003 -#endif - -#define DISPLAY_COUNT 1 - -namespace android { - -// --------------------------------------------------------------------------- - -void SurfaceFlinger::instantiate() { - defaultServiceManager()->addService( - String16("SurfaceFlinger"), new SurfaceFlinger()); -} - -void SurfaceFlinger::shutdown() { - // we should unregister here, but not really because - // when (if) the service manager goes away, all the services - // it has a reference to will leave too. -} - -// --------------------------------------------------------------------------- - -SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs) - : lookup(rhs.lookup), layers(rhs.layers) -{ -} - -ssize_t SurfaceFlinger::LayerVector::indexOf( - const sp<LayerBase>& key, size_t guess) const -{ - if (guess<size() && lookup.keyAt(guess) == key) - return guess; - const ssize_t i = lookup.indexOfKey(key); - if (i>=0) { - const size_t idx = lookup.valueAt(i); - LOGE_IF(layers[idx]!=key, - "LayerVector[%p]: layers[%d]=%p, key=%p", - this, int(idx), layers[idx].get(), key.get()); - return idx; - } - return i; -} - -ssize_t SurfaceFlinger::LayerVector::add( - const sp<LayerBase>& layer, - Vector< sp<LayerBase> >::compar_t cmp) -{ - size_t count = layers.size(); - ssize_t l = 0; - ssize_t h = count-1; - ssize_t mid; - sp<LayerBase> const* a = layers.array(); - while (l <= h) { - mid = l + (h - l)/2; - const int c = cmp(a+mid, &layer); - if (c == 0) { l = mid; break; } - else if (c<0) { l = mid+1; } - else { h = mid-1; } - } - size_t order = l; - while (order<count && !cmp(&layer, a+order)) { - order++; - } - count = lookup.size(); - for (size_t i=0 ; i<count ; i++) { - if (lookup.valueAt(i) >= order) { - lookup.editValueAt(i)++; - } - } - layers.insertAt(layer, order); - lookup.add(layer, order); - return order; -} - -ssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer) -{ - const ssize_t keyIndex = lookup.indexOfKey(layer); - if (keyIndex >= 0) { - const size_t index = lookup.valueAt(keyIndex); - LOGE_IF(layers[index]!=layer, - "LayerVector[%p]: layers[%u]=%p, layer=%p", - this, int(index), layers[index].get(), layer.get()); - layers.removeItemsAt(index); - lookup.removeItemsAt(keyIndex); - const size_t count = lookup.size(); - for (size_t i=0 ; i<count ; i++) { - if (lookup.valueAt(i) >= size_t(index)) { - lookup.editValueAt(i)--; - } - } - return index; - } - return NAME_NOT_FOUND; -} - -ssize_t SurfaceFlinger::LayerVector::reorder( - const sp<LayerBase>& layer, - Vector< sp<LayerBase> >::compar_t cmp) -{ - // XXX: it's a little lame. but oh well... - ssize_t err = remove(layer); - if (err >=0) - err = add(layer, cmp); - return err; -} - -// --------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -SurfaceFlinger::SurfaceFlinger() - : BnSurfaceComposer(), Thread(false), - mTransactionFlags(0), - mTransactionCount(0), - mResizeTransationPending(false), - mLayersRemoved(false), - mBootTime(systemTime()), - mHardwareTest("android.permission.HARDWARE_TEST"), - mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"), - mDump("android.permission.DUMP"), - mVisibleRegionsDirty(false), - mDeferReleaseConsole(false), - mFreezeDisplay(false), - mFreezeCount(0), - mFreezeDisplayTime(0), - mDebugRegion(0), - mDebugBackground(0), - mDebugInSwapBuffers(0), - mLastSwapBufferTime(0), - mDebugInTransaction(0), - mLastTransactionTime(0), - mBootFinished(false), - mConsoleSignals(0), - mSecureFrameBuffer(0) -{ - init(); -} - -void SurfaceFlinger::init() -{ - LOGI("SurfaceFlinger is starting"); - - // debugging stuff... - char value[PROPERTY_VALUE_MAX]; - property_get("debug.sf.showupdates", value, "0"); - mDebugRegion = atoi(value); - property_get("debug.sf.showbackground", value, "0"); - mDebugBackground = atoi(value); - - LOGI_IF(mDebugRegion, "showupdates enabled"); - LOGI_IF(mDebugBackground, "showbackground enabled"); -} - -SurfaceFlinger::~SurfaceFlinger() -{ - glDeleteTextures(1, &mWormholeTexName); -} - -overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const -{ - return graphicPlane(0).displayHardware().getOverlayEngine(); -} - -sp<IMemoryHeap> SurfaceFlinger::getCblk() const -{ - return mServerHeap; -} - -sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() -{ - sp<ISurfaceComposerClient> bclient; - sp<Client> client(new Client(this)); - status_t err = client->initCheck(); - if (err == NO_ERROR) { - bclient = client; - } - return bclient; -} - -sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection() -{ - sp<ISurfaceComposerClient> bclient; - sp<UserClient> client(new UserClient(this)); - status_t err = client->initCheck(); - if (err == NO_ERROR) { - bclient = client; - } - return bclient; -} - - -const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const -{ - LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); - const GraphicPlane& plane(mGraphicPlanes[dpy]); - return plane; -} - -GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) -{ - return const_cast<GraphicPlane&>( - const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); -} - -void SurfaceFlinger::bootFinished() -{ - const nsecs_t now = systemTime(); - const nsecs_t duration = now - mBootTime; - LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); - mBootFinished = true; - property_set("ctl.stop", "bootanim"); -} - -void SurfaceFlinger::onFirstRef() -{ - run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); - - // Wait for the main thread to be done with its initialization - mReadyToRunBarrier.wait(); -} - -static inline uint16_t pack565(int r, int g, int b) { - return (r<<11)|(g<<5)|b; -} - -status_t SurfaceFlinger::readyToRun() -{ - LOGI( "SurfaceFlinger's main thread ready to run. " - "Initializing graphics H/W..."); - - // we only support one display currently - int dpy = 0; - - { - // initialize the main display - GraphicPlane& plane(graphicPlane(dpy)); - DisplayHardware* const hw = new DisplayHardware(this, dpy); - plane.setDisplayHardware(hw); - } - - // create the shared control-block - mServerHeap = new MemoryHeapBase(4096, - MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); - LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); - - mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); - LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); - - new(mServerCblk) surface_flinger_cblk_t; - - // initialize primary screen - // (other display should be initialized in the same manner, but - // asynchronously, as they could come and go. None of this is supported - // yet). - const GraphicPlane& plane(graphicPlane(dpy)); - const DisplayHardware& hw = plane.displayHardware(); - const uint32_t w = hw.getWidth(); - const uint32_t h = hw.getHeight(); - const uint32_t f = hw.getFormat(); - hw.makeCurrent(); - - // initialize the shared control block - mServerCblk->connected |= 1<<dpy; - display_cblk_t* dcblk = mServerCblk->displays + dpy; - memset(dcblk, 0, sizeof(display_cblk_t)); - dcblk->w = plane.getWidth(); - dcblk->h = plane.getHeight(); - dcblk->format = f; - dcblk->orientation = ISurfaceComposer::eOrientationDefault; - dcblk->xdpi = hw.getDpiX(); - dcblk->ydpi = hw.getDpiY(); - dcblk->fps = hw.getRefreshRate(); - dcblk->density = hw.getDensity(); - - // Initialize OpenGL|ES - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_PACK_ALIGNMENT, 4); - glEnableClientState(GL_VERTEX_ARRAY); - glEnable(GL_SCISSOR_TEST); - glShadeModel(GL_FLAT); - glDisable(GL_DITHER); - glDisable(GL_CULL_FACE); - - const uint16_t g0 = pack565(0x0F,0x1F,0x0F); - const uint16_t g1 = pack565(0x17,0x2f,0x17); - const uint16_t textureData[4] = { g0, g1, g1, g0 }; - glGenTextures(1, &mWormholeTexName); - glBindTexture(GL_TEXTURE_2D, mWormholeTexName); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); - - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof(0, w, h, 0, 0, 1); - - LayerDim::initDimmer(this, w, h); - - mReadyToRunBarrier.open(); - - /* - * We're now ready to accept clients... - */ - - // start boot animation - property_set("ctl.start", "bootanim"); - - return NO_ERROR; -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Events Handler -#endif - -void SurfaceFlinger::waitForEvent() -{ - while (true) { - nsecs_t timeout = -1; - const nsecs_t freezeDisplayTimeout = ms2ns(5000); - if (UNLIKELY(isFrozen())) { - // wait 5 seconds - const nsecs_t now = systemTime(); - if (mFreezeDisplayTime == 0) { - mFreezeDisplayTime = now; - } - nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); - timeout = waitTime>0 ? waitTime : 0; - } - - sp<MessageBase> msg = mEventQueue.waitMessage(timeout); - - // see if we timed out - if (isFrozen()) { - const nsecs_t now = systemTime(); - nsecs_t frozenTime = (now - mFreezeDisplayTime); - if (frozenTime >= freezeDisplayTimeout) { - // we timed out and are still frozen - LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", - mFreezeDisplay, mFreezeCount); - mFreezeDisplayTime = 0; - mFreezeCount = 0; - mFreezeDisplay = false; - } - } - - if (msg != 0) { - switch (msg->what) { - case MessageQueue::INVALIDATE: - // invalidate message, just return to the main loop - return; - } - } - } -} - -void SurfaceFlinger::signalEvent() { - mEventQueue.invalidate(); -} - -void SurfaceFlinger::signal() const { - // this is the IPC call - const_cast<SurfaceFlinger*>(this)->signalEvent(); -} - -status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, - nsecs_t reltime, uint32_t flags) -{ - return mEventQueue.postMessage(msg, reltime, flags); -} - -status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, - nsecs_t reltime, uint32_t flags) -{ - status_t res = mEventQueue.postMessage(msg, reltime, flags); - if (res == NO_ERROR) { - msg->wait(); - } - return res; -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Main loop -#endif - -bool SurfaceFlinger::threadLoop() -{ - waitForEvent(); - - // check for transactions - if (UNLIKELY(mConsoleSignals)) { - handleConsoleEvents(); - } - - if (LIKELY(mTransactionCount == 0)) { - // if we're in a global transaction, don't do anything. - const uint32_t mask = eTransactionNeeded | eTraversalNeeded; - uint32_t transactionFlags = getTransactionFlags(mask); - if (LIKELY(transactionFlags)) { - handleTransaction(transactionFlags); - } - } - - // post surfaces (if needed) - handlePageFlip(); - - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - if (LIKELY(hw.canDraw() && !isFrozen())) { - // repaint the framebuffer (if needed) - handleRepaint(); - - // inform the h/w that we're done compositing - hw.compositionComplete(); - - // release the clients before we flip ('cause flip might block) - unlockClients(); - - postFramebuffer(); - } else { - // pretend we did the post - unlockClients(); - usleep(16667); // 60 fps period - } - return true; -} - -void SurfaceFlinger::postFramebuffer() -{ - if (!mInvalidRegion.isEmpty()) { - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const nsecs_t now = systemTime(); - mDebugInSwapBuffers = now; - hw.flip(mInvalidRegion); - mLastSwapBufferTime = systemTime() - now; - mDebugInSwapBuffers = 0; - mInvalidRegion.clear(); - } -} - -void SurfaceFlinger::handleConsoleEvents() -{ - // something to do with the console - const DisplayHardware& hw = graphicPlane(0).displayHardware(); - - int what = android_atomic_and(0, &mConsoleSignals); - if (what & eConsoleAcquired) { - hw.acquireScreen(); - } - - if (mDeferReleaseConsole && hw.canDraw()) { - // We got the release signal before the acquire signal - mDeferReleaseConsole = false; - hw.releaseScreen(); - } - - if (what & eConsoleReleased) { - if (hw.canDraw()) { - hw.releaseScreen(); - } else { - mDeferReleaseConsole = true; - } - } - - mDirtyRegion.set(hw.bounds()); -} - -void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) -{ - Vector< sp<LayerBase> > ditchedLayers; - - { // scope for the lock - Mutex::Autolock _l(mStateLock); - const nsecs_t now = systemTime(); - mDebugInTransaction = now; - handleTransactionLocked(transactionFlags, ditchedLayers); - mLastTransactionTime = systemTime() - now; - mDebugInTransaction = 0; - } - - // do this without lock held - const size_t count = ditchedLayers.size(); - for (size_t i=0 ; i<count ; i++) { - if (ditchedLayers[i] != 0) { - //LOGD("ditching layer %p", ditchedLayers[i].get()); - ditchedLayers[i]->ditch(); - } - } -} - -void SurfaceFlinger::handleTransactionLocked( - uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers) -{ - const LayerVector& currentLayers(mCurrentState.layersSortedByZ); - const size_t count = currentLayers.size(); - - /* - * Traversal of the children - * (perform the transaction for each of them if needed) - */ - - const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; - if (layersNeedTransaction) { - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer = currentLayers[i]; - uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); - if (!trFlags) continue; - - const uint32_t flags = layer->doTransaction(0); - if (flags & Layer::eVisibleRegion) - mVisibleRegionsDirty = true; - } - } - - /* - * Perform our own transaction if needed - */ - - if (transactionFlags & eTransactionNeeded) { - if (mCurrentState.orientation != mDrawingState.orientation) { - // the orientation has changed, recompute all visible regions - // and invalidate everything. - - const int dpy = 0; - const int orientation = mCurrentState.orientation; - const uint32_t type = mCurrentState.orientationType; - GraphicPlane& plane(graphicPlane(dpy)); - plane.setOrientation(orientation); - - // update the shared control block - const DisplayHardware& hw(plane.displayHardware()); - volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; - dcblk->orientation = orientation; - dcblk->w = plane.getWidth(); - dcblk->h = plane.getHeight(); - - mVisibleRegionsDirty = true; - mDirtyRegion.set(hw.bounds()); - } - - if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { - // freezing or unfreezing the display -> trigger animation if needed - mFreezeDisplay = mCurrentState.freezeDisplay; - if (mFreezeDisplay) - mFreezeDisplayTime = 0; - } - - if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { - // layers have been added - mVisibleRegionsDirty = true; - } - - // some layers might have been removed, so - // we need to update the regions they're exposing. - if (mLayersRemoved) { - mLayersRemoved = false; - mVisibleRegionsDirty = true; - const LayerVector& previousLayers(mDrawingState.layersSortedByZ); - const size_t count = previousLayers.size(); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(previousLayers[i]); - if (currentLayers.indexOf( layer ) < 0) { - // this layer is not visible anymore - ditchedLayers.add(layer); - mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); - } - } - } - } - - commitTransaction(); -} - -sp<FreezeLock> SurfaceFlinger::getFreezeLock() const -{ - return new FreezeLock(const_cast<SurfaceFlinger *>(this)); -} - -void SurfaceFlinger::computeVisibleRegions( - LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) -{ - const GraphicPlane& plane(graphicPlane(0)); - const Transform& planeTransform(plane.transform()); - const DisplayHardware& hw(plane.displayHardware()); - const Region screenRegion(hw.bounds()); - - Region aboveOpaqueLayers; - Region aboveCoveredLayers; - Region dirty; - - bool secureFrameBuffer = false; - - size_t i = currentLayers.size(); - while (i--) { - const sp<LayerBase>& layer = currentLayers[i]; - layer->validateVisibility(planeTransform); - - // start with the whole surface at its current location - const Layer::State& s(layer->drawingState()); - - /* - * opaqueRegion: area of a surface that is fully opaque. - */ - Region opaqueRegion; - - /* - * visibleRegion: area of a surface that is visible on screen - * and not fully transparent. This is essentially the layer's - * footprint minus the opaque regions above it. - * Areas covered by a translucent surface are considered visible. - */ - Region visibleRegion; - - /* - * coveredRegion: area of a surface that is covered by all - * visible regions above it (which includes the translucent areas). - */ - Region coveredRegion; - - - // handle hidden surfaces by setting the visible region to empty - if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { - const bool translucent = layer->needsBlending(); - const Rect bounds(layer->visibleBounds()); - visibleRegion.set(bounds); - visibleRegion.andSelf(screenRegion); - if (!visibleRegion.isEmpty()) { - // Remove the transparent area from the visible region - if (translucent) { - visibleRegion.subtractSelf(layer->transparentRegionScreen); - } - - // compute the opaque region - const int32_t layerOrientation = layer->getOrientation(); - if (s.alpha==255 && !translucent && - ((layerOrientation & Transform::ROT_INVALID) == false)) { - // the opaque region is the layer's footprint - opaqueRegion = visibleRegion; - } - } - } - - // Clip the covered region to the visible region - coveredRegion = aboveCoveredLayers.intersect(visibleRegion); - - // Update aboveCoveredLayers for next (lower) layer - aboveCoveredLayers.orSelf(visibleRegion); - - // subtract the opaque region covered by the layers above us - visibleRegion.subtractSelf(aboveOpaqueLayers); - - // compute this layer's dirty region - if (layer->contentDirty) { - // we need to invalidate the whole region - dirty = visibleRegion; - // as well, as the old visible region - dirty.orSelf(layer->visibleRegionScreen); - layer->contentDirty = false; - } else { - /* compute the exposed region: - * the exposed region consists of two components: - * 1) what's VISIBLE now and was COVERED before - * 2) what's EXPOSED now less what was EXPOSED before - * - * note that (1) is conservative, we start with the whole - * visible region but only keep what used to be covered by - * something -- which mean it may have been exposed. - * - * (2) handles areas that were not covered by anything but got - * exposed because of a resize. - */ - const Region newExposed = visibleRegion - coveredRegion; - const Region oldVisibleRegion = layer->visibleRegionScreen; - const Region oldCoveredRegion = layer->coveredRegionScreen; - const Region oldExposed = oldVisibleRegion - oldCoveredRegion; - dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); - } - dirty.subtractSelf(aboveOpaqueLayers); - - // accumulate to the screen dirty region - dirtyRegion.orSelf(dirty); - - // Update aboveOpaqueLayers for next (lower) layer - aboveOpaqueLayers.orSelf(opaqueRegion); - - // Store the visible region is screen space - layer->setVisibleRegion(visibleRegion); - layer->setCoveredRegion(coveredRegion); - - // If a secure layer is partially visible, lock-down the screen! - if (layer->isSecure() && !visibleRegion.isEmpty()) { - secureFrameBuffer = true; - } - } - - // invalidate the areas where a layer was removed - dirtyRegion.orSelf(mDirtyRegionRemovedLayer); - mDirtyRegionRemovedLayer.clear(); - - mSecureFrameBuffer = secureFrameBuffer; - opaqueRegion = aboveOpaqueLayers; -} - - -void SurfaceFlinger::commitTransaction() -{ - mDrawingState = mCurrentState; - mResizeTransationPending = false; - mTransactionCV.broadcast(); -} - -void SurfaceFlinger::handlePageFlip() -{ - bool visibleRegions = mVisibleRegionsDirty; - LayerVector& currentLayers = const_cast<LayerVector&>( - mDrawingState.layersSortedByZ); - visibleRegions |= lockPageFlip(currentLayers); - - const DisplayHardware& hw = graphicPlane(0).displayHardware(); - const Region screenRegion(hw.bounds()); - if (visibleRegions) { - Region opaqueRegion; - computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); - mWormholeRegion = screenRegion.subtract(opaqueRegion); - mVisibleRegionsDirty = false; - } - - unlockPageFlip(currentLayers); - mDirtyRegion.andSelf(screenRegion); -} - -bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) -{ - bool recomputeVisibleRegions = false; - size_t count = currentLayers.size(); - sp<LayerBase> const* layers = currentLayers.array(); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(layers[i]); - layer->lockPageFlip(recomputeVisibleRegions); - } - return recomputeVisibleRegions; -} - -void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) -{ - const GraphicPlane& plane(graphicPlane(0)); - const Transform& planeTransform(plane.transform()); - size_t count = currentLayers.size(); - sp<LayerBase> const* layers = currentLayers.array(); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(layers[i]); - layer->unlockPageFlip(planeTransform, mDirtyRegion); - } -} - - -void SurfaceFlinger::handleRepaint() -{ - // compute the invalid region - mInvalidRegion.orSelf(mDirtyRegion); - if (mInvalidRegion.isEmpty()) { - // nothing to do - return; - } - - if (UNLIKELY(mDebugRegion)) { - debugFlashRegions(); - } - - // set the frame buffer - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - uint32_t flags = hw.getFlags(); - if ((flags & DisplayHardware::SWAP_RECTANGLE) || - (flags & DisplayHardware::BUFFER_PRESERVED)) - { - // we can redraw only what's dirty, but since SWAP_RECTANGLE only - // takes a rectangle, we must make sure to update that whole - // rectangle in that case - if (flags & DisplayHardware::SWAP_RECTANGLE) { - // TODO: we really should be able to pass a region to - // SWAP_RECTANGLE so that we don't have to redraw all this. - mDirtyRegion.set(mInvalidRegion.bounds()); - } else { - // in the BUFFER_PRESERVED case, obviously, we can update only - // what's needed and nothing more. - // NOTE: this is NOT a common case, as preserving the backbuffer - // is costly and usually involves copying the whole update back. - } - } else { - if (flags & DisplayHardware::PARTIAL_UPDATES) { - // We need to redraw the rectangle that will be updated - // (pushed to the framebuffer). - // This is needed because PARTIAL_UPDATES only takes one - // rectangle instead of a region (see DisplayHardware::flip()) - mDirtyRegion.set(mInvalidRegion.bounds()); - } else { - // we need to redraw everything (the whole screen) - mDirtyRegion.set(hw.bounds()); - mInvalidRegion = mDirtyRegion; - } - } - - // compose all surfaces - composeSurfaces(mDirtyRegion); - - // clear the dirty regions - mDirtyRegion.clear(); -} - -void SurfaceFlinger::composeSurfaces(const Region& dirty) -{ - if (UNLIKELY(!mWormholeRegion.isEmpty())) { - // should never happen unless the window manager has a bug - // draw something... - drawWormhole(); - } - const SurfaceFlinger& flinger(*this); - const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); - const size_t count = drawingLayers.size(); - sp<LayerBase> const* const layers = drawingLayers.array(); - for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer = layers[i]; - const Region& visibleRegion(layer->visibleRegionScreen); - if (!visibleRegion.isEmpty()) { - const Region clip(dirty.intersect(visibleRegion)); - if (!clip.isEmpty()) { - layer->draw(clip); - } - } - } -} - -void SurfaceFlinger::unlockClients() -{ - const LayerVector& drawingLayers(mDrawingState.layersSortedByZ); - const size_t count = drawingLayers.size(); - sp<LayerBase> const* const layers = drawingLayers.array(); - for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer = layers[i]; - layer->finishPageFlip(); - } -} - -void SurfaceFlinger::debugFlashRegions() -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t flags = hw.getFlags(); - - if (!((flags & DisplayHardware::SWAP_RECTANGLE) || - (flags & DisplayHardware::BUFFER_PRESERVED))) { - const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? - mDirtyRegion.bounds() : hw.bounds()); - composeSurfaces(repaint); - } - - TextureManager::deactivateTextures(); - - glDisable(GL_BLEND); - glDisable(GL_DITHER); - glDisable(GL_SCISSOR_TEST); - - static int toggle = 0; - toggle = 1 - toggle; - if (toggle) { - glColor4f(1, 0, 1, 1); - } else { - glColor4f(1, 1, 0, 1); - } - - Region::const_iterator it = mDirtyRegion.begin(); - Region::const_iterator const end = mDirtyRegion.end(); - while (it != end) { - const Rect& r = *it++; - GLfloat vertices[][2] = { - { r.left, r.top }, - { r.left, r.bottom }, - { r.right, r.bottom }, - { r.right, r.top } - }; - glVertexPointer(2, GL_FLOAT, 0, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - if (mInvalidRegion.isEmpty()) { - mDirtyRegion.dump("mDirtyRegion"); - mInvalidRegion.dump("mInvalidRegion"); - } - hw.flip(mInvalidRegion); - - if (mDebugRegion > 1) - usleep(mDebugRegion * 1000); - - glEnable(GL_SCISSOR_TEST); - //mDirtyRegion.dump("mDirtyRegion"); -} - -void SurfaceFlinger::drawWormhole() const -{ - const Region region(mWormholeRegion.intersect(mDirtyRegion)); - if (region.isEmpty()) - return; - - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const int32_t width = hw.getWidth(); - const int32_t height = hw.getHeight(); - - glDisable(GL_BLEND); - glDisable(GL_DITHER); - - if (LIKELY(!mDebugBackground)) { - glClearColor(0,0,0,0); - Region::const_iterator it = region.begin(); - Region::const_iterator const end = region.end(); - while (it != end) { - const Rect& r = *it++; - const GLint sy = height - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glClear(GL_COLOR_BUFFER_BIT); - } - } else { - const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, - { width, height }, { 0, height } }; - const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; - glVertexPointer(2, GL_SHORT, 0, vertices); - glTexCoordPointer(2, GL_SHORT, 0, tcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -#if defined(GL_OES_texture_external) - if (GLExtensions::getInstance().haveTextureExternal()) { - glDisable(GL_TEXTURE_EXTERNAL_OES); - } -#endif - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, mWormholeTexName); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); - Region::const_iterator it = region.begin(); - Region::const_iterator const end = region.end(); - while (it != end) { - const Rect& r = *it++; - const GLint sy = height - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -void SurfaceFlinger::debugShowFPS() const -{ - static int mFrameCount; - static int mLastFrameCount = 0; - static nsecs_t mLastFpsTime = 0; - static float mFps = 0; - mFrameCount++; - nsecs_t now = systemTime(); - nsecs_t diff = now - mLastFpsTime; - if (diff > ms2ns(250)) { - mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; - mLastFpsTime = now; - mLastFrameCount = mFrameCount; - } - // XXX: mFPS has the value we want - } - -status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) -{ - Mutex::Autolock _l(mStateLock); - addLayer_l(layer); - setTransactionFlags(eTransactionNeeded|eTraversalNeeded); - return NO_ERROR; -} - -status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) -{ - ssize_t i = mCurrentState.layersSortedByZ.add( - layer, &LayerBase::compareCurrentStateZ); - return (i < 0) ? status_t(i) : status_t(NO_ERROR); -} - -ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, - const sp<LayerBaseClient>& lbc) -{ - Mutex::Autolock _l(mStateLock); - - // attach this layer to the client - ssize_t name = client->attachLayer(lbc); - - // add this layer to the current state list - addLayer_l(lbc); - - return name; -} - -status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) -{ - Mutex::Autolock _l(mStateLock); - status_t err = purgatorizeLayer_l(layer); - if (err == NO_ERROR) - setTransactionFlags(eTransactionNeeded); - return err; -} - -status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) -{ - sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); - if (lbc != 0) { - mLayerMap.removeItem( lbc->getSurface()->asBinder() ); - } - ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); - if (index >= 0) { - mLayersRemoved = true; - return NO_ERROR; - } - return status_t(index); -} - -status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) -{ - // remove the layer from the main list (through a transaction). - ssize_t err = removeLayer_l(layerBase); - - layerBase->onRemoved(); - - // it's possible that we don't find a layer, because it might - // have been destroyed already -- this is not technically an error - // from the user because there is a race between Client::destroySurface(), - // ~Client() and ~ISurface(). - return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; -} - -status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) -{ - layer->forceVisibilityTransaction(); - setTransactionFlags(eTraversalNeeded); - return NO_ERROR; -} - -uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) -{ - return android_atomic_and(~flags, &mTransactionFlags) & flags; -} - -uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) -{ - uint32_t old = android_atomic_or(flags, &mTransactionFlags); - if ((old & flags)==0) { // wake the server up - signalEvent(); - } - return old; -} - -void SurfaceFlinger::openGlobalTransaction() -{ - android_atomic_inc(&mTransactionCount); -} - -void SurfaceFlinger::closeGlobalTransaction() -{ - if (android_atomic_dec(&mTransactionCount) == 1) { - signalEvent(); - - // if there is a transaction with a resize, wait for it to - // take effect before returning. - Mutex::Autolock _l(mStateLock); - while (mResizeTransationPending) { - status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); - if (CC_UNLIKELY(err != NO_ERROR)) { - // just in case something goes wrong in SF, return to the - // called after a few seconds. - LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); - mResizeTransationPending = false; - break; - } - } - } -} - -status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) -{ - if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) - return BAD_VALUE; - - Mutex::Autolock _l(mStateLock); - mCurrentState.freezeDisplay = 1; - setTransactionFlags(eTransactionNeeded); - - // flags is intended to communicate some sort of animation behavior - // (for instance fading) - return NO_ERROR; -} - -status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) -{ - if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) - return BAD_VALUE; - - Mutex::Autolock _l(mStateLock); - mCurrentState.freezeDisplay = 0; - setTransactionFlags(eTransactionNeeded); - - // flags is intended to communicate some sort of animation behavior - // (for instance fading) - return NO_ERROR; -} - -int SurfaceFlinger::setOrientation(DisplayID dpy, - int orientation, uint32_t flags) -{ - if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) - return BAD_VALUE; - - Mutex::Autolock _l(mStateLock); - if (mCurrentState.orientation != orientation) { - if (uint32_t(orientation)<=eOrientation270 || orientation==42) { - mCurrentState.orientationType = flags; - mCurrentState.orientation = orientation; - setTransactionFlags(eTransactionNeeded); - mTransactionCV.wait(mStateLock); - } else { - orientation = BAD_VALUE; - } - } - return orientation; -} - -sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid, - const String8& name, ISurfaceComposerClient::surface_data_t* params, - DisplayID d, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) -{ - sp<LayerBaseClient> layer; - sp<LayerBaseClient::Surface> surfaceHandle; - - if (int32_t(w|h) < 0) { - LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", - int(w), int(h)); - return surfaceHandle; - } - - //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); - sp<Layer> normalLayer; - switch (flags & eFXSurfaceMask) { - case eFXSurfaceNormal: - if (UNLIKELY(flags & ePushBuffers)) { - layer = createPushBuffersSurface(client, d, w, h, flags); - } else { - normalLayer = createNormalSurface(client, d, w, h, flags, format); - layer = normalLayer; - } - break; - case eFXSurfaceBlur: - layer = createBlurSurface(client, d, w, h, flags); - break; - case eFXSurfaceDim: - layer = createDimSurface(client, d, w, h, flags); - break; - } - - if (layer != 0) { - layer->initStates(w, h, flags); - layer->setName(name); - ssize_t token = addClientLayer(client, layer); - - surfaceHandle = layer->getSurface(); - if (surfaceHandle != 0) { - params->token = token; - params->identity = surfaceHandle->getIdentity(); - params->width = w; - params->height = h; - params->format = format; - if (normalLayer != 0) { - Mutex::Autolock _l(mStateLock); - mLayerMap.add(surfaceHandle->asBinder(), normalLayer); - } - } - - setTransactionFlags(eTransactionNeeded); - } - - return surfaceHandle; -} - -sp<Layer> SurfaceFlinger::createNormalSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags, - PixelFormat& format) -{ - // initialize the surfaces - switch (format) { // TODO: take h/w into account - case PIXEL_FORMAT_TRANSPARENT: - case PIXEL_FORMAT_TRANSLUCENT: - format = PIXEL_FORMAT_RGBA_8888; - break; - case PIXEL_FORMAT_OPAQUE: -#ifdef NO_RGBX_8888 - format = PIXEL_FORMAT_RGB_565; -#else - format = PIXEL_FORMAT_RGBX_8888; -#endif - break; - } - -#ifdef NO_RGBX_8888 - if (format == PIXEL_FORMAT_RGBX_8888) - format = PIXEL_FORMAT_RGBA_8888; -#endif - - sp<Layer> layer = new Layer(this, display, client); - status_t err = layer->setBuffers(w, h, format, flags); - if (LIKELY(err != NO_ERROR)) { - LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); - layer.clear(); - } - return layer; -} - -sp<LayerBlur> SurfaceFlinger::createBlurSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags) -{ - sp<LayerBlur> layer = new LayerBlur(this, display, client); - layer->initStates(w, h, flags); - return layer; -} - -sp<LayerDim> SurfaceFlinger::createDimSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags) -{ - sp<LayerDim> layer = new LayerDim(this, display, client); - layer->initStates(w, h, flags); - return layer; -} - -sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags) -{ - sp<LayerBuffer> layer = new LayerBuffer(this, display, client); - layer->initStates(w, h, flags); - return layer; -} - -status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) -{ - /* - * called by the window manager, when a surface should be marked for - * destruction. - * - * The surface is removed from the current and drawing lists, but placed - * in the purgatory queue, so it's not destroyed right-away (we need - * to wait for all client's references to go away first). - */ - - status_t err = NAME_NOT_FOUND; - Mutex::Autolock _l(mStateLock); - sp<LayerBaseClient> layer = client->getLayerUser(sid); - if (layer != 0) { - err = purgatorizeLayer_l(layer); - if (err == NO_ERROR) { - setTransactionFlags(eTransactionNeeded); - } - } - return err; -} - -status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer) -{ - // called by ~ISurface() when all references are gone - - class MessageDestroySurface : public MessageBase { - SurfaceFlinger* flinger; - sp<LayerBaseClient> layer; - public: - MessageDestroySurface( - SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer) - : flinger(flinger), layer(layer) { } - virtual bool handler() { - sp<LayerBaseClient> l(layer); - layer.clear(); // clear it outside of the lock; - Mutex::Autolock _l(flinger->mStateLock); - /* - * remove the layer from the current list -- chances are that it's - * not in the list anyway, because it should have been removed - * already upon request of the client (eg: window manager). - * However, a buggy client could have not done that. - * Since we know we don't have any more clients, we don't need - * to use the purgatory. - */ - status_t err = flinger->removeLayer_l(l); - LOGE_IF(err<0 && err != NAME_NOT_FOUND, - "error removing layer=%p (%s)", l.get(), strerror(-err)); - return true; - } - }; - - postMessageAsync( new MessageDestroySurface(this, layer) ); - return NO_ERROR; -} - -status_t SurfaceFlinger::setClientState( - const sp<Client>& client, - int32_t count, - const layer_state_t* states) -{ - Mutex::Autolock _l(mStateLock); - uint32_t flags = 0; - for (int i=0 ; i<count ; i++) { - const layer_state_t& s(states[i]); - sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); - if (layer != 0) { - const uint32_t what = s.what; - if (what & ePositionChanged) { - if (layer->setPosition(s.x, s.y)) - flags |= eTraversalNeeded; - } - if (what & eLayerChanged) { - if (layer->setLayer(s.z)) { - mCurrentState.layersSortedByZ.reorder( - layer, &Layer::compareCurrentStateZ); - // we need traversal (state changed) - // AND transaction (list changed) - flags |= eTransactionNeeded|eTraversalNeeded; - } - } - if (what & eSizeChanged) { - if (layer->setSize(s.w, s.h)) { - flags |= eTraversalNeeded; - mResizeTransationPending = true; - } - } - if (what & eAlphaChanged) { - if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) - flags |= eTraversalNeeded; - } - if (what & eMatrixChanged) { - if (layer->setMatrix(s.matrix)) - flags |= eTraversalNeeded; - } - if (what & eTransparentRegionChanged) { - if (layer->setTransparentRegionHint(s.transparentRegion)) - flags |= eTraversalNeeded; - } - if (what & eVisibilityChanged) { - if (layer->setFlags(s.flags, s.mask)) - flags |= eTraversalNeeded; - } - } - } - if (flags) { - setTransactionFlags(flags); - } - return NO_ERROR; -} - -void SurfaceFlinger::screenReleased(int dpy) -{ - // this may be called by a signal handler, we can't do too much in here - android_atomic_or(eConsoleReleased, &mConsoleSignals); - signalEvent(); -} - -void SurfaceFlinger::screenAcquired(int dpy) -{ - // this may be called by a signal handler, we can't do too much in here - android_atomic_or(eConsoleAcquired, &mConsoleSignals); - signalEvent(); -} - -status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) -{ - const size_t SIZE = 1024; - char buffer[SIZE]; - String8 result; - if (!mDump.checkCalling()) { - snprintf(buffer, SIZE, "Permission Denial: " - "can't dump SurfaceFlinger from pid=%d, uid=%d\n", - IPCThreadState::self()->getCallingPid(), - IPCThreadState::self()->getCallingUid()); - result.append(buffer); - } else { - - // figure out if we're stuck somewhere - const nsecs_t now = systemTime(); - const nsecs_t inSwapBuffers(mDebugInSwapBuffers); - const nsecs_t inTransaction(mDebugInTransaction); - nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; - nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; - - // Try to get the main lock, but don't insist if we can't - // (this would indicate SF is stuck, but we want to be able to - // print something in dumpsys). - int retry = 3; - while (mStateLock.tryLock()<0 && --retry>=0) { - usleep(1000000); - } - const bool locked(retry >= 0); - if (!locked) { - snprintf(buffer, SIZE, - "SurfaceFlinger appears to be unresponsive, " - "dumping anyways (no locks held)\n"); - result.append(buffer); - } - - const LayerVector& currentLayers = mCurrentState.layersSortedByZ; - const size_t count = currentLayers.size(); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); - layer->dump(result, buffer, SIZE); - const Layer::State& s(layer->drawingState()); - s.transparentRegion.dump(result, "transparentRegion"); - layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); - layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); - } - - mWormholeRegion.dump(result, "WormholeRegion"); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - snprintf(buffer, SIZE, - " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", - mFreezeDisplay?"yes":"no", mFreezeCount, - mCurrentState.orientation, hw.canDraw()); - result.append(buffer); - snprintf(buffer, SIZE, - " last eglSwapBuffers() time: %f us\n" - " last transaction time : %f us\n", - mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); - result.append(buffer); - - if (inSwapBuffersDuration || !locked) { - snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", - inSwapBuffersDuration/1000.0); - result.append(buffer); - } - - if (inTransactionDuration || !locked) { - snprintf(buffer, SIZE, " transaction time: %f us\n", - inTransactionDuration/1000.0); - result.append(buffer); - } - - const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); - alloc.dump(result); - - if (locked) { - mStateLock.unlock(); - } - } - write(fd, result.string(), result.size()); - return NO_ERROR; -} - -status_t SurfaceFlinger::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case CREATE_CONNECTION: - case OPEN_GLOBAL_TRANSACTION: - case CLOSE_GLOBAL_TRANSACTION: - case SET_ORIENTATION: - case FREEZE_DISPLAY: - case UNFREEZE_DISPLAY: - case BOOT_FINISHED: - { - // codes that require permission check - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) { - LOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - } - } - status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); - if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { - CHECK_INTERFACE(ISurfaceComposer, data, reply); - if (UNLIKELY(!mHardwareTest.checkCalling())) { - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - LOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - int n; - switch (code) { - case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE - return NO_ERROR; - case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE - return NO_ERROR; - case 1002: // SHOW_UPDATES - n = data.readInt32(); - mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); - return NO_ERROR; - case 1003: // SHOW_BACKGROUND - n = data.readInt32(); - mDebugBackground = n ? 1 : 0; - return NO_ERROR; - case 1004:{ // repaint everything - Mutex::Autolock _l(mStateLock); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe - signalEvent(); - return NO_ERROR; - } - case 1005:{ // force transaction - setTransactionFlags(eTransactionNeeded|eTraversalNeeded); - return NO_ERROR; - } - case 1007: // set mFreezeCount - mFreezeCount = data.readInt32(); - mFreezeDisplayTime = 0; - return NO_ERROR; - case 1010: // interrogate. - reply->writeInt32(0); - reply->writeInt32(0); - reply->writeInt32(mDebugRegion); - reply->writeInt32(mDebugBackground); - return NO_ERROR; - case 1013: { - Mutex::Autolock _l(mStateLock); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - reply->writeInt32(hw.getPageFlipCount()); - } - return NO_ERROR; - } - } - return err; -} - -// --------------------------------------------------------------------------- - -sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const -{ - sp<Layer> result; - Mutex::Autolock _l(mStateLock); - result = mLayerMap.valueFor( sur->asBinder() ).promote(); - return result; -} - -// --------------------------------------------------------------------------- - -Client::Client(const sp<SurfaceFlinger>& flinger) - : mFlinger(flinger), mNameGenerator(1) -{ -} - -Client::~Client() -{ - const size_t count = mLayers.size(); - for (size_t i=0 ; i<count ; i++) { - sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); - if (layer != 0) { - mFlinger->removeLayer(layer); - } - } -} - -status_t Client::initCheck() const { - return NO_ERROR; -} - -ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer) -{ - int32_t name = android_atomic_inc(&mNameGenerator); - mLayers.add(name, layer); - return name; -} - -void Client::detachLayer(const LayerBaseClient* layer) -{ - // we do a linear search here, because this doesn't happen often - const size_t count = mLayers.size(); - for (size_t i=0 ; i<count ; i++) { - if (mLayers.valueAt(i) == layer) { - mLayers.removeItemsAt(i, 1); - break; - } - } -} -sp<LayerBaseClient> Client::getLayerUser(int32_t i) const { - sp<LayerBaseClient> lbc; - const wp<LayerBaseClient>& layer(mLayers.valueFor(i)); - if (layer != 0) { - lbc = layer.promote(); - LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); - } - return lbc; -} - -sp<IMemoryHeap> Client::getControlBlock() const { - return 0; -} -ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const { - return -1; -} -sp<ISurface> Client::createSurface( - ISurfaceComposerClient::surface_data_t* params, int pid, - const String8& name, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) -{ - return mFlinger->createSurface(this, pid, name, params, - display, w, h, format, flags); -} -status_t Client::destroySurface(SurfaceID sid) { - return mFlinger->removeSurface(this, sid); -} -status_t Client::setState(int32_t count, const layer_state_t* states) { - return mFlinger->setClientState(this, count, states); -} - -// --------------------------------------------------------------------------- - -UserClient::UserClient(const sp<SurfaceFlinger>& flinger) - : ctrlblk(0), mBitmap(0), mFlinger(flinger) -{ - const int pgsize = getpagesize(); - const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); - - mCblkHeap = new MemoryHeapBase(cblksize, 0, - "SurfaceFlinger Client control-block"); - - ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); - if (ctrlblk) { // construct the shared structure in-place. - new(ctrlblk) SharedClient; - } -} - -UserClient::~UserClient() -{ - if (ctrlblk) { - ctrlblk->~SharedClient(); // destroy our shared-structure. - } - - /* - * When a UserClient dies, it's unclear what to do exactly. - * We could go ahead and destroy all surfaces linked to that client - * however, it wouldn't be fair to the main Client - * (usually the the window-manager), which might want to re-target - * the layer to another UserClient. - * I think the best is to do nothing, or not much; in most cases the - * WM itself will go ahead and clean things up when it detects a client of - * his has died. - * The remaining question is what to display? currently we keep - * just keep the current buffer. - */ -} - -status_t UserClient::initCheck() const { - return ctrlblk == 0 ? NO_INIT : NO_ERROR; -} - -void UserClient::detachLayer(const Layer* layer) -{ - int32_t name = layer->getToken(); - if (name >= 0) { - int32_t mask = 1LU<<name; - if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) { - LOGW("token %d wasn't marked as used %08x", name, int(mBitmap)); - } - } -} - -sp<IMemoryHeap> UserClient::getControlBlock() const { - return mCblkHeap; -} - -ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const -{ - int32_t name = NAME_NOT_FOUND; - sp<Layer> layer(mFlinger->getLayer(sur)); - if (layer == 0) return name; - - // if this layer already has a token, just return it - name = layer->getToken(); - if ((name >= 0) && (layer->getClient() == this)) - return name; - - name = 0; - do { - int32_t mask = 1LU<<name; - if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { - // we found and locked that name - status_t err = layer->setToken( - const_cast<UserClient*>(this), ctrlblk, name); - if (err != NO_ERROR) { - // free the name - android_atomic_and(~mask, &mBitmap); - name = err; - } - break; - } - if (++name > 31) - name = NO_MEMORY; - } while(name >= 0); - - //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)", - // sur->asBinder().get(), name, this, mBitmap); - return name; -} - -sp<ISurface> UserClient::createSurface( - ISurfaceComposerClient::surface_data_t* params, int pid, - const String8& name, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) { - return 0; -} -status_t UserClient::destroySurface(SurfaceID sid) { - return INVALID_OPERATION; -} -status_t UserClient::setState(int32_t count, const layer_state_t* states) { - return INVALID_OPERATION; -} - -// --------------------------------------------------------------------------- - -GraphicPlane::GraphicPlane() - : mHw(0) -{ -} - -GraphicPlane::~GraphicPlane() { - delete mHw; -} - -bool GraphicPlane::initialized() const { - return mHw ? true : false; -} - -int GraphicPlane::getWidth() const { - return mWidth; -} - -int GraphicPlane::getHeight() const { - return mHeight; -} - -void GraphicPlane::setDisplayHardware(DisplayHardware *hw) -{ - mHw = hw; - - // initialize the display orientation transform. - // it's a constant that should come from the display driver. - int displayOrientation = ISurfaceComposer::eOrientationDefault; - char property[PROPERTY_VALUE_MAX]; - if (property_get("ro.sf.hwrotation", property, NULL) > 0) { - //displayOrientation - switch (atoi(property)) { - case 90: - displayOrientation = ISurfaceComposer::eOrientation90; - break; - case 270: - displayOrientation = ISurfaceComposer::eOrientation270; - break; - } - } - - const float w = hw->getWidth(); - const float h = hw->getHeight(); - GraphicPlane::orientationToTransfrom(displayOrientation, w, h, - &mDisplayTransform); - if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { - mDisplayWidth = h; - mDisplayHeight = w; - } else { - mDisplayWidth = w; - mDisplayHeight = h; - } - - setOrientation(ISurfaceComposer::eOrientationDefault); -} - -status_t GraphicPlane::orientationToTransfrom( - int orientation, int w, int h, Transform* tr) -{ - uint32_t flags = 0; - switch (orientation) { - case ISurfaceComposer::eOrientationDefault: - flags = Transform::ROT_0; - break; - case ISurfaceComposer::eOrientation90: - flags = Transform::ROT_90; - break; - case ISurfaceComposer::eOrientation180: - flags = Transform::ROT_180; - break; - case ISurfaceComposer::eOrientation270: - flags = Transform::ROT_270; - break; - default: - return BAD_VALUE; - } - tr->set(flags, w, h); - return NO_ERROR; -} - -status_t GraphicPlane::setOrientation(int orientation) -{ - // If the rotation can be handled in hardware, this is where - // the magic should happen. - - const DisplayHardware& hw(displayHardware()); - const float w = mDisplayWidth; - const float h = mDisplayHeight; - mWidth = int(w); - mHeight = int(h); - - Transform orientationTransform; - GraphicPlane::orientationToTransfrom(orientation, w, h, - &orientationTransform); - if (orientation & ISurfaceComposer::eOrientationSwapMask) { - mWidth = int(h); - mHeight = int(w); - } - - mOrientation = orientation; - mGlobalTransform = mDisplayTransform * orientationTransform; - return NO_ERROR; -} - -const DisplayHardware& GraphicPlane::displayHardware() const { - return *mHw; -} - -const Transform& GraphicPlane::transform() const { - return mGlobalTransform; -} - -EGLDisplay GraphicPlane::getEGLDisplay() const { - return mHw->getEGLDisplay(); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h deleted file mode 100644 index 0bfc170..0000000 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ /dev/null @@ -1,420 +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. - */ - -#ifndef ANDROID_SURFACE_FLINGER_H -#define ANDROID_SURFACE_FLINGER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/SortedVector.h> -#include <utils/KeyedVector.h> -#include <utils/threads.h> -#include <utils/Atomic.h> -#include <utils/Errors.h> -#include <utils/RefBase.h> - -#include <binder/IMemory.h> -#include <binder/Permission.h> - -#include <ui/PixelFormat.h> -#include <surfaceflinger/ISurfaceComposer.h> -#include <surfaceflinger/ISurfaceComposerClient.h> - -#include "Barrier.h" -#include "Layer.h" - -#include "MessageQueue.h" - -struct copybit_device_t; -struct overlay_device_t; - -namespace android { - -// --------------------------------------------------------------------------- - -class Client; -class DisplayHardware; -class FreezeLock; -class Layer; -class LayerBlur; -class LayerDim; -class LayerBuffer; - -#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) -#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) - -// --------------------------------------------------------------------------- - -class Client : public BnSurfaceComposerClient -{ -public: - Client(const sp<SurfaceFlinger>& flinger); - ~Client(); - - status_t initCheck() const; - - // protected by SurfaceFlinger::mStateLock - ssize_t attachLayer(const sp<LayerBaseClient>& layer); - void detachLayer(const LayerBaseClient* layer); - sp<LayerBaseClient> getLayerUser(int32_t i) const; - -private: - - // ISurfaceComposerClient interface - virtual sp<IMemoryHeap> getControlBlock() const; - virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const; - virtual sp<ISurface> createSurface( - surface_data_t* params, int pid, const String8& name, - DisplayID display, uint32_t w, uint32_t h,PixelFormat format, - uint32_t flags); - virtual status_t destroySurface(SurfaceID surfaceId); - virtual status_t setState(int32_t count, const layer_state_t* states); - - DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers; - sp<SurfaceFlinger> mFlinger; - int32_t mNameGenerator; -}; - -class UserClient : public BnSurfaceComposerClient -{ -public: - // pointer to this client's control block - SharedClient* ctrlblk; - -public: - UserClient(const sp<SurfaceFlinger>& flinger); - ~UserClient(); - - status_t initCheck() const; - - // protected by SurfaceFlinger::mStateLock - void detachLayer(const Layer* layer); - -private: - - // ISurfaceComposerClient interface - virtual sp<IMemoryHeap> getControlBlock() const; - virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const; - virtual sp<ISurface> createSurface( - surface_data_t* params, int pid, const String8& name, - DisplayID display, uint32_t w, uint32_t h,PixelFormat format, - uint32_t flags); - virtual status_t destroySurface(SurfaceID surfaceId); - virtual status_t setState(int32_t count, const layer_state_t* states); - - // atomic-ops - mutable volatile int32_t mBitmap; - - sp<IMemoryHeap> mCblkHeap; - sp<SurfaceFlinger> mFlinger; -}; - -// --------------------------------------------------------------------------- - -class GraphicPlane -{ -public: - static status_t orientationToTransfrom(int orientation, int w, int h, - Transform* tr); - - GraphicPlane(); - ~GraphicPlane(); - - bool initialized() const; - - void setDisplayHardware(DisplayHardware *); - status_t setOrientation(int orientation); - int getOrientation() const { return mOrientation; } - int getWidth() const; - int getHeight() const; - - const DisplayHardware& displayHardware() const; - const Transform& transform() const; - EGLDisplay getEGLDisplay() const; - -private: - GraphicPlane(const GraphicPlane&); - GraphicPlane operator = (const GraphicPlane&); - - DisplayHardware* mHw; - Transform mGlobalTransform; - Transform mDisplayTransform; - int mOrientation; - float mDisplayWidth; - float mDisplayHeight; - int mWidth; - int mHeight; -}; - -// --------------------------------------------------------------------------- - -enum { - eTransactionNeeded = 0x01, - eTraversalNeeded = 0x02 -}; - -class SurfaceFlinger : public BnSurfaceComposer, protected Thread -{ -public: - static void instantiate(); - static void shutdown(); - - SurfaceFlinger(); - virtual ~SurfaceFlinger(); - void init(); - - virtual status_t onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); - - virtual status_t dump(int fd, const Vector<String16>& args); - - // ISurfaceComposer interface - virtual sp<ISurfaceComposerClient> createConnection(); - virtual sp<ISurfaceComposerClient> createClientConnection(); - virtual sp<IMemoryHeap> getCblk() const; - virtual void bootFinished(); - virtual void openGlobalTransaction(); - virtual void closeGlobalTransaction(); - virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags); - virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); - virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); - virtual void signal() const; - - void screenReleased(DisplayID dpy); - void screenAcquired(DisplayID dpy); - - overlay_control_device_t* getOverlayEngine() const; - - status_t removeLayer(const sp<LayerBase>& layer); - status_t addLayer(const sp<LayerBase>& layer); - status_t invalidateLayerVisibility(const sp<LayerBase>& layer); - - sp<Layer> getLayer(const sp<ISurface>& sur) const; - -private: - friend class Client; - friend class LayerBase; - friend class LayerBuffer; - friend class LayerBaseClient; - friend class LayerBaseClient::Surface; - friend class Layer; - friend class LayerBlur; - friend class LayerDim; - - sp<ISurface> createSurface(const sp<Client>& client, - int pid, const String8& name, - ISurfaceComposerClient::surface_data_t* params, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags); - - sp<Layer> createNormalSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags, - PixelFormat& format); - - sp<LayerBlur> createBlurSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); - - sp<LayerDim> createDimSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); - - sp<LayerBuffer> createPushBuffersSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); - - status_t removeSurface(const sp<Client>& client, SurfaceID sid); - status_t destroySurface(const sp<LayerBaseClient>& layer); - status_t setClientState(const sp<Client>& client, - int32_t count, const layer_state_t* states); - - - class LayerVector { - public: - inline LayerVector() { } - LayerVector(const LayerVector&); - inline size_t size() const { return layers.size(); } - inline sp<LayerBase> const* array() const { return layers.array(); } - ssize_t add(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t); - ssize_t remove(const sp<LayerBase>&); - ssize_t reorder(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t); - ssize_t indexOf(const sp<LayerBase>& key, size_t guess=0) const; - inline sp<LayerBase> operator [] (size_t i) const { return layers[i]; } - private: - KeyedVector< sp<LayerBase> , size_t> lookup; - Vector< sp<LayerBase> > layers; - }; - - struct State { - State() { - orientation = ISurfaceComposer::eOrientationDefault; - freezeDisplay = 0; - } - LayerVector layersSortedByZ; - uint8_t orientation; - uint8_t orientationType; - uint8_t freezeDisplay; - }; - - virtual bool threadLoop(); - virtual status_t readyToRun(); - virtual void onFirstRef(); - -public: // hack to work around gcc 4.0.3 bug - const GraphicPlane& graphicPlane(int dpy) const; - GraphicPlane& graphicPlane(int dpy); -private: - - void waitForEvent(); -public: // hack to work around gcc 4.0.3 bug - void signalEvent(); -private: - void handleConsoleEvents(); - void handleTransaction(uint32_t transactionFlags); - void handleTransactionLocked( - uint32_t transactionFlags, - Vector< sp<LayerBase> >& ditchedLayers); - - void computeVisibleRegions( - LayerVector& currentLayers, - Region& dirtyRegion, - Region& wormholeRegion); - - void handlePageFlip(); - bool lockPageFlip(const LayerVector& currentLayers); - void unlockPageFlip(const LayerVector& currentLayers); - void handleRepaint(); - void postFramebuffer(); - void composeSurfaces(const Region& dirty); - void unlockClients(); - - - ssize_t addClientLayer(const sp<Client>& client, - const sp<LayerBaseClient>& lbc); - status_t addLayer_l(const sp<LayerBase>& layer); - status_t removeLayer_l(const sp<LayerBase>& layer); - status_t purgatorizeLayer_l(const sp<LayerBase>& layer); - - uint32_t getTransactionFlags(uint32_t flags); - uint32_t setTransactionFlags(uint32_t flags); - void commitTransaction(); - - - friend class FreezeLock; - sp<FreezeLock> getFreezeLock() const; - inline void incFreezeCount() { - if (mFreezeCount == 0) - mFreezeDisplayTime = 0; - mFreezeCount++; - } - inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; } - inline bool hasFreezeRequest() const { return mFreezeDisplay; } - inline bool isFrozen() const { - return (mFreezeDisplay || mFreezeCount>0) && mBootFinished; - } - - - void debugFlashRegions(); - void debugShowFPS() const; - void drawWormhole() const; - - - mutable MessageQueue mEventQueue; - - status_t postMessageAsync(const sp<MessageBase>& msg, - nsecs_t reltime=0, uint32_t flags = 0); - - status_t postMessageSync(const sp<MessageBase>& msg, - nsecs_t reltime=0, uint32_t flags = 0); - - // access must be protected by mStateLock - mutable Mutex mStateLock; - State mCurrentState; - State mDrawingState; - volatile int32_t mTransactionFlags; - volatile int32_t mTransactionCount; - Condition mTransactionCV; - bool mResizeTransationPending; - - // protected by mStateLock (but we could use another lock) - GraphicPlane mGraphicPlanes[1]; - bool mLayersRemoved; - DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap; - - // constant members (no synchronization needed for access) - sp<IMemoryHeap> mServerHeap; - surface_flinger_cblk_t* mServerCblk; - GLuint mWormholeTexName; - nsecs_t mBootTime; - Permission mHardwareTest; - Permission mAccessSurfaceFlinger; - Permission mDump; - - // Can only accessed from the main thread, these members - // don't need synchronization - Region mDirtyRegion; - Region mDirtyRegionRemovedLayer; - Region mInvalidRegion; - Region mWormholeRegion; - bool mVisibleRegionsDirty; - bool mDeferReleaseConsole; - bool mFreezeDisplay; - int32_t mFreezeCount; - nsecs_t mFreezeDisplayTime; - - // don't use a lock for these, we don't care - int mDebugRegion; - int mDebugBackground; - volatile nsecs_t mDebugInSwapBuffers; - nsecs_t mLastSwapBufferTime; - volatile nsecs_t mDebugInTransaction; - nsecs_t mLastTransactionTime; - bool mBootFinished; - - // these are thread safe - mutable Barrier mReadyToRunBarrier; - - // atomic variables - enum { - eConsoleReleased = 1, - eConsoleAcquired = 2 - }; - volatile int32_t mConsoleSignals; - - // only written in the main thread, only read in other threads - volatile int32_t mSecureFrameBuffer; -}; - -// --------------------------------------------------------------------------- - -class FreezeLock : public LightRefBase<FreezeLock> { - SurfaceFlinger* mFlinger; -public: - FreezeLock(SurfaceFlinger* flinger) - : mFlinger(flinger) { - mFlinger->incFreezeCount(); - } - ~FreezeLock() { - mFlinger->decFreezeCount(); - } -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SURFACE_FLINGER_H diff --git a/libs/surfaceflinger/TextureManager.cpp b/libs/surfaceflinger/TextureManager.cpp deleted file mode 100644 index 3b326df..0000000 --- a/libs/surfaceflinger/TextureManager.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/Log.h> - -#include <ui/GraphicBuffer.h> - -#include <GLES/gl.h> -#include <GLES/glext.h> - -#include <hardware/hardware.h> - -#include "clz.h" -#include "DisplayHardware/DisplayHardware.h" -#include "GLExtensions.h" -#include "TextureManager.h" - -namespace android { - -// --------------------------------------------------------------------------- - -TextureManager::TextureManager() - : mGLExtensions(GLExtensions::getInstance()) -{ -} - -GLenum TextureManager::getTextureTarget(const Image* image) { -#if defined(GL_OES_texture_external) - switch (image->target) { - case Texture::TEXTURE_EXTERNAL: - return GL_TEXTURE_EXTERNAL_OES; - } -#endif - return GL_TEXTURE_2D; -} - -status_t TextureManager::initTexture(Texture* texture) -{ - if (texture->name != -1UL) - return INVALID_OPERATION; - - GLuint textureName = -1; - glGenTextures(1, &textureName); - texture->name = textureName; - texture->width = 0; - texture->height = 0; - - const GLenum target = GL_TEXTURE_2D; - glBindTexture(target, textureName); - glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - return NO_ERROR; -} - -status_t TextureManager::initTexture(Image* pImage, int32_t format) -{ - if (pImage->name != -1UL) - return INVALID_OPERATION; - - GLuint textureName = -1; - glGenTextures(1, &textureName); - pImage->name = textureName; - pImage->width = 0; - pImage->height = 0; - - GLenum target = GL_TEXTURE_2D; -#if defined(GL_OES_texture_external) - if (GLExtensions::getInstance().haveTextureExternal()) { - if (format && isYuvFormat(format)) { - target = GL_TEXTURE_EXTERNAL_OES; - pImage->target = Texture::TEXTURE_EXTERNAL; - } - } -#endif - - glBindTexture(target, textureName); - glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - return NO_ERROR; -} - -bool TextureManager::isSupportedYuvFormat(int format) -{ - switch (format) { - case HAL_PIXEL_FORMAT_YV12: - return true; - } - return false; -} - -bool TextureManager::isYuvFormat(int format) -{ - switch (format) { - // supported YUV formats - case HAL_PIXEL_FORMAT_YV12: - // Legacy/deprecated YUV formats - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YCbCr_422_I: - case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: - return true; - } - - // Any OEM format needs to be considered - if (format>=0x100 && format<=0x1FF) - return true; - - return false; -} - -status_t TextureManager::initEglImage(Image* pImage, - EGLDisplay dpy, const sp<GraphicBuffer>& buffer) -{ - status_t err = NO_ERROR; - if (!pImage->dirty) return err; - - // free the previous image - if (pImage->image != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(dpy, pImage->image); - pImage->image = EGL_NO_IMAGE_KHR; - } - - // construct an EGL_NATIVE_BUFFER_ANDROID - android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); - - // create the new EGLImageKHR - const EGLint attrs[] = { - EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, - EGL_NONE, EGL_NONE - }; - pImage->image = eglCreateImageKHR( - dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - (EGLClientBuffer)clientBuf, attrs); - - if (pImage->image != EGL_NO_IMAGE_KHR) { - if (pImage->name == -1UL) { - initTexture(pImage, buffer->format); - } - const GLenum target = getTextureTarget(pImage); - glBindTexture(target, pImage->name); - glEGLImageTargetTexture2DOES(target, (GLeglImageOES)pImage->image); - GLint error = glGetError(); - if (error != GL_NO_ERROR) { - LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x", - pImage->image, error); - err = INVALID_OPERATION; - } else { - // Everything went okay! - pImage->dirty = false; - pImage->width = clientBuf->width; - pImage->height = clientBuf->height; - } - } else { - LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError()); - err = INVALID_OPERATION; - } - return err; -} - -status_t TextureManager::loadTexture(Texture* texture, - const Region& dirty, const GGLSurface& t) -{ - if (texture->name == -1UL) { - status_t err = initTexture(texture); - LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err)); - return err; - } - - if (texture->target != GL_TEXTURE_2D) - return INVALID_OPERATION; - - glBindTexture(GL_TEXTURE_2D, texture->name); - - /* - * In OpenGL ES we can't specify a stride with glTexImage2D (however, - * GL_UNPACK_ALIGNMENT is 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 - */ - - int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); - unpack = 1 << ((unpack > 3) ? 3 : unpack); - glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); - - /* - * round to POT if needed - */ - if (!mGLExtensions.haveNpot()) { - texture->NPOTAdjust = true; - } - - if (texture->NPOTAdjust) { - // find the smallest power-of-two that will accommodate our surface - texture->potWidth = 1 << (31 - clz(t.width)); - texture->potHeight = 1 << (31 - clz(t.height)); - if (texture->potWidth < t.width) texture->potWidth <<= 1; - if (texture->potHeight < t.height) texture->potHeight <<= 1; - texture->wScale = float(t.width) / texture->potWidth; - texture->hScale = float(t.height) / texture->potHeight; - } else { - texture->potWidth = t.width; - texture->potHeight = t.height; - } - - Rect bounds(dirty.bounds()); - GLvoid* data = 0; - if (texture->width != t.width || texture->height != t.height) { - texture->width = t.width; - texture->height = t.height; - - // texture size changed, we need to create a new one - bounds.set(Rect(t.width, t.height)); - if (t.width == texture->potWidth && - t.height == texture->potHeight) { - // we can do it one pass - data = t.data; - } - - if (t.format == HAL_PIXEL_FORMAT_RGB_565) { - glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGB, texture->potWidth, texture->potHeight, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); - } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { - glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, texture->potWidth, texture->potHeight, 0, - GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); - } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || - t.format == HAL_PIXEL_FORMAT_RGBX_8888) { - glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, texture->potWidth, texture->potHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, data); - } else if (isSupportedYuvFormat(t.format)) { - // just show the Y plane of YUV buffers - glTexImage2D(GL_TEXTURE_2D, 0, - GL_LUMINANCE, texture->potWidth, texture->potHeight, 0, - GL_LUMINANCE, GL_UNSIGNED_BYTE, data); - } else { - // oops, we don't handle this format! - LOGE("texture=%d, using format %d, which is not " - "supported by the GL", texture->name, t.format); - } - } - if (!data) { - if (t.format == HAL_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.stride*2); - } else if (t.format == HAL_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.stride*2); - } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || - t.format == HAL_PIXEL_FORMAT_RGBX_8888) { - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, bounds.top, t.width, bounds.height(), - GL_RGBA, GL_UNSIGNED_BYTE, - t.data + bounds.top*t.stride*4); - } else if (isSupportedYuvFormat(t.format)) { - // just show the Y plane of YUV buffers - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, bounds.top, t.width, bounds.height(), - GL_LUMINANCE, GL_UNSIGNED_BYTE, - t.data + bounds.top*t.stride); - } - } - return NO_ERROR; -} - -void TextureManager::activateTexture(const Texture& texture, bool filter) -{ - const GLenum target = getTextureTarget(&texture); - if (target == GL_TEXTURE_2D) { - glBindTexture(GL_TEXTURE_2D, texture.name); - glEnable(GL_TEXTURE_2D); -#if defined(GL_OES_texture_external) - if (GLExtensions::getInstance().haveTextureExternal()) { - glDisable(GL_TEXTURE_EXTERNAL_OES); - } - } else { - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture.name); - glEnable(GL_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); -#endif - } - - if (filter) { - glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } -} - -void TextureManager::deactivateTextures() -{ - glDisable(GL_TEXTURE_2D); -#if defined(GL_OES_texture_external) - if (GLExtensions::getInstance().haveTextureExternal()) { - glDisable(GL_TEXTURE_EXTERNAL_OES); - } -#endif -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/TextureManager.h b/libs/surfaceflinger/TextureManager.h deleted file mode 100644 index c7c14e7..0000000 --- a/libs/surfaceflinger/TextureManager.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#ifndef ANDROID_TEXTURE_MANAGER_H -#define ANDROID_TEXTURE_MANAGER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> - -#include <ui/Region.h> - -#include <pixelflinger/pixelflinger.h> - -namespace android { - -// --------------------------------------------------------------------------- - -class GLExtensions; -class GraphicBuffer; - -// --------------------------------------------------------------------------- - -struct Image { - enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 }; - Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0), - transform(0), dirty(1), target(TEXTURE_2D) { } - GLuint name; - EGLImageKHR image; - GLuint width; - GLuint height; - uint32_t transform; - unsigned dirty : 1; - unsigned target : 1; -}; - -struct Texture : public Image { - Texture() : Image(), NPOTAdjust(0) { } - GLuint potWidth; - GLuint potHeight; - GLfloat wScale; - GLfloat hScale; - unsigned NPOTAdjust : 1; -}; - -// --------------------------------------------------------------------------- - -class TextureManager { - const GLExtensions& mGLExtensions; - static status_t initTexture(Image* texture, int32_t format); - static status_t initTexture(Texture* texture); - static bool isSupportedYuvFormat(int format); - static bool isYuvFormat(int format); - static GLenum getTextureTarget(const Image* pImage); -public: - - TextureManager(); - - // load bitmap data into the active buffer - status_t loadTexture(Texture* texture, - const Region& dirty, const GGLSurface& t); - - // make active buffer an EGLImage if needed - status_t initEglImage(Image* texture, - EGLDisplay dpy, const sp<GraphicBuffer>& buffer); - - // activate a texture - static void activateTexture(const Texture& texture, bool filter); - - // deactivate a texture - static void deactivateTextures(); -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_TEXTURE_MANAGER_H diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp deleted file mode 100644 index 5e27cc9..0000000 --- a/libs/surfaceflinger/Transform.cpp +++ /dev/null @@ -1,391 +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. - */ - -#include <math.h> - -#include <cutils/compiler.h> -#include <utils/String8.h> -#include <ui/Region.h> - -#include "Transform.h" - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -template <typename T> inline T min(T a, T b) { - return a<b ? a : b; -} -template <typename T> inline T min(T a, T b, T c) { - return min(a, min(b, c)); -} -template <typename T> inline T min(T a, T b, T c, T d) { - return min(a, b, min(c, d)); -} - -template <typename T> inline T max(T a, T b) { - return a>b ? a : b; -} -template <typename T> inline T max(T a, T b, T c) { - return max(a, max(b, c)); -} -template <typename T> inline T max(T a, T b, T c, T d) { - return max(a, b, max(c, d)); -} - -// --------------------------------------------------------------------------- - -Transform::Transform() { - reset(); -} - -Transform::Transform(const Transform& other) - : mMatrix(other.mMatrix), mType(other.mType) { -} - -Transform::Transform(uint32_t orientation) { - set(orientation, 0, 0); -} - -Transform::~Transform() { -} - -static const float EPSILON = 0.0f; - -bool Transform::isZero(float f) { - return fabs(f) <= EPSILON; -} - -bool Transform::absIsOne(float f) { - return isZero(fabs(f) - 1.0f); -} - -Transform Transform::operator * (const Transform& rhs) const -{ - if (CC_LIKELY(mType == IDENTITY)) - return rhs; - - Transform r(*this); - if (rhs.mType == IDENTITY) - return r; - - // TODO: we could use mType to optimize the matrix multiply - const mat33& A(mMatrix); - const mat33& B(rhs.mMatrix); - mat33& D(r.mMatrix); - for (int i=0 ; i<3 ; i++) { - const float v0 = A[0][i]; - const float v1 = A[1][i]; - const float v2 = A[2][i]; - D[0][i] = v0*B[0][0] + v1*B[0][1] + v2*B[0][2]; - D[1][i] = v0*B[1][0] + v1*B[1][1] + v2*B[1][2]; - D[2][i] = v0*B[2][0] + v1*B[2][1] + v2*B[2][2]; - } - r.mType |= rhs.mType; - - // TODO: we could recompute this value from r and rhs - r.mType &= 0xFF; - r.mType |= UNKNOWN_TYPE; - return r; -} - -float const* Transform::operator [] (int i) const { - return mMatrix[i].v; -} - -bool Transform::transformed() const { - return type() > TRANSLATE; -} - -int Transform::tx() const { - return floorf(mMatrix[2][0] + 0.5f); -} - -int Transform::ty() const { - return floorf(mMatrix[2][1] + 0.5f); -} - -void Transform::reset() { - mType = IDENTITY; - for(int i=0 ; i<3 ; i++) { - vec3& v(mMatrix[i]); - for (int j=0 ; j<3 ; j++) - v[j] = ((i==j) ? 1.0f : 0.0f); - } -} - -void Transform::set(float tx, float ty) -{ - mMatrix[2][0] = tx; - mMatrix[2][1] = ty; - mMatrix[2][2] = 1.0f; - - if (isZero(tx) && isZero(ty)) { - mType &= ~TRANSLATE; - } else { - mType |= TRANSLATE; - } -} - -void Transform::set(float a, float b, float c, float d) -{ - mat33& M(mMatrix); - M[0][0] = a; M[1][0] = b; - M[0][1] = c; M[1][1] = d; - M[0][2] = 0; M[1][2] = 0; - mType = UNKNOWN_TYPE; -} - -status_t Transform::set(uint32_t flags, float w, float h) -{ - if (flags & ROT_INVALID) { - // that's not allowed! - reset(); - return BAD_VALUE; - } - - mType = flags << 8; - float sx = (flags & FLIP_H) ? -1 : 1; - float sy = (flags & FLIP_V) ? -1 : 1; - float a=0, b=0, c=0, d=0, x=0, y=0; - int xmask = 0; - - // computation of x,y - // x y - // 0 0 0 - // w 0 ROT90 - // w h FLIPH|FLIPV - // 0 h FLIPH|FLIPV|ROT90 - - if (flags & ROT_90) { - mType |= ROTATE; - b = -sy; - c = sx; - xmask = 1; - } else { - a = sx; - d = sy; - } - - if (flags & FLIP_H) { - mType ^= SCALE; - xmask ^= 1; - } - - if (flags & FLIP_V) { - mType ^= SCALE; - y = h; - } - - if ((flags & ROT_180) == ROT_180) { - mType |= ROTATE; - } - - if (xmask) { - x = w; - } - - if (!isZero(x) || !isZero(y)) { - mType |= TRANSLATE; - } - - mat33& M(mMatrix); - M[0][0] = a; M[1][0] = b; M[2][0] = x; - M[0][1] = c; M[1][1] = d; M[2][1] = y; - M[0][2] = 0; M[1][2] = 0; M[2][2] = 1; - - return NO_ERROR; -} - -Transform::vec2 Transform::transform(const vec2& v) const { - vec2 r; - const mat33& M(mMatrix); - r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0]; - r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1]; - return r; -} - -Transform::vec3 Transform::transform(const vec3& v) const { - vec3 r; - const mat33& M(mMatrix); - r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0]*v[2]; - r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1]*v[2]; - r[2] = M[0][2]*v[0] + M[1][2]*v[1] + M[2][2]*v[2]; - return r; -} - -void Transform::transform(float* point, int x, int y) const -{ - const mat33& M(mMatrix); - vec2 v(x, y); - v = transform(v); - point[0] = v[0]; - point[1] = v[1]; -} - -Rect Transform::makeBounds(int w, int h) const -{ - return transform( Rect(w, h) ); -} - -Rect Transform::transform(const Rect& bounds) const -{ - Rect r; - vec2 lt( bounds.left, bounds.top ); - vec2 rt( bounds.right, bounds.top ); - vec2 lb( bounds.left, bounds.bottom ); - vec2 rb( bounds.right, bounds.bottom ); - - lt = transform(lt); - rt = transform(rt); - lb = transform(lb); - rb = transform(rb); - - r.left = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f); - r.top = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f); - r.right = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f); - r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f); - - return r; -} - -Region Transform::transform(const Region& reg) const -{ - Region out; - if (CC_UNLIKELY(transformed())) { - if (CC_LIKELY(preserveRects())) { - Region::const_iterator it = reg.begin(); - Region::const_iterator const end = reg.end(); - while (it != end) { - out.orSelf(transform(*it++)); - } - } else { - out.set(transform(reg.bounds())); - } - } else { - out = reg.translate(tx(), ty()); - } - return out; -} - -uint32_t Transform::type() const -{ - if (mType & UNKNOWN_TYPE) { - // recompute what this transform is - - const mat33& M(mMatrix); - const float a = M[0][0]; - const float b = M[1][0]; - const float c = M[0][1]; - const float d = M[1][1]; - const float x = M[2][0]; - const float y = M[2][1]; - - bool scale = false; - uint32_t flags = ROT_0; - if (isZero(b) && isZero(c)) { - if (a<0) flags |= FLIP_H; - if (d<0) flags |= FLIP_V; - if (!absIsOne(a) || !absIsOne(d)) { - scale = true; - } - } else if (isZero(a) && isZero(d)) { - flags |= ROT_90; - if (b>0) flags |= FLIP_H; - if (c<0) flags |= FLIP_V; - if (!absIsOne(b) || !absIsOne(c)) { - scale = true; - } - } else { - flags = ROT_INVALID; - } - - mType = flags << 8; - if (flags & ROT_INVALID) { - mType |= UNKNOWN; - } else { - if ((flags & ROT_90) || ((flags & ROT_180) == ROT_180)) - mType |= ROTATE; - if (flags & FLIP_H) - mType ^= SCALE; - if (flags & FLIP_V) - mType ^= SCALE; - if (scale) - mType |= SCALE; - } - - if (!isZero(x) || !isZero(y)) - mType |= TRANSLATE; - } - return mType; -} - -uint32_t Transform::getType() const { - return type() & 0xFF; -} - -uint32_t Transform::getOrientation() const -{ - return (type() >> 8) & 0xFF; -} - -bool Transform::preserveRects() const -{ - return (type() & ROT_INVALID) ? false : true; -} - -void Transform::dump(const char* name) const -{ - type(); // updates the type - - String8 flags, type; - const mat33& m(mMatrix); - uint32_t orient = mType >> 8; - - if (orient&ROT_INVALID) { - flags.append("ROT_INVALID "); - } else { - if (orient&ROT_90) { - flags.append("ROT_90 "); - } else { - flags.append("ROT_0 "); - } - if (orient&FLIP_V) - flags.append("FLIP_V "); - if (orient&FLIP_H) - flags.append("FLIP_H "); - } - - if (!(mType&(SCALE|ROTATE|TRANSLATE))) - type.append("IDENTITY "); - if (mType&SCALE) - type.append("SCALE "); - if (mType&ROTATE) - type.append("ROTATE "); - if (mType&TRANSLATE) - type.append("TRANSLATE "); - - LOGD("%s 0x%08x (%s, %s)", name, mType, flags.string(), type.string()); - LOGD("%.4f %.4f %.4f", m[0][0], m[1][0], m[2][0]); - LOGD("%.4f %.4f %.4f", m[0][1], m[1][1], m[2][1]); - LOGD("%.4f %.4f %.4f", m[0][2], m[1][2], m[2][2]); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h deleted file mode 100644 index 20fa11a..0000000 --- a/libs/surfaceflinger/Transform.h +++ /dev/null @@ -1,126 +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. - */ - -#ifndef ANDROID_TRANSFORM_H -#define ANDROID_TRANSFORM_H - -#include <stdint.h> -#include <sys/types.h> - -#include <ui/Point.h> -#include <ui/Rect.h> - -namespace android { - -class Region; - -// --------------------------------------------------------------------------- - -class Transform -{ -public: - Transform(); - Transform(const Transform& other); - explicit Transform(uint32_t orientation); - ~Transform(); - - // FIXME: must match OVERLAY_TRANSFORM_*, pull from hardware.h - enum orientation_flags { - ROT_0 = 0x00000000, - FLIP_H = 0x00000001, - FLIP_V = 0x00000002, - ROT_90 = 0x00000004, - ROT_180 = FLIP_H|FLIP_V, - ROT_270 = ROT_180|ROT_90, - ROT_INVALID = 0x80 - }; - - enum type_mask { - IDENTITY = 0, - TRANSLATE = 0x1, - ROTATE = 0x2, - SCALE = 0x4, - UNKNOWN = 0x8 - }; - - // query the transform - bool transformed() const; - bool preserveRects() const; - uint32_t getType() const; - uint32_t getOrientation() const; - - float const* operator [] (int i) const; // returns column i - int tx() const; - int ty() const; - - // modify the transform - void reset(); - void set(float tx, float ty); - void set(float a, float b, float c, float d); - status_t set(uint32_t flags, float w, float h); - - // transform data - Rect makeBounds(int w, int h) const; - void transform(float* point, int x, int y) const; - Region transform(const Region& reg) const; - Transform operator * (const Transform& rhs) const; - - // for debugging - void dump(const char* name) const; - -private: - struct vec3 { - float v[3]; - inline vec3() { } - inline vec3(float a, float b, float c) { - v[0] = a; v[1] = b; v[2] = c; - } - inline float operator [] (int i) const { return v[i]; } - inline float& operator [] (int i) { return v[i]; } - }; - struct vec2 { - float v[2]; - inline vec2() { } - inline vec2(float a, float b) { - v[0] = a; v[1] = b; - } - inline float operator [] (int i) const { return v[i]; } - inline float& operator [] (int i) { return v[i]; } - }; - struct mat33 { - vec3 v[3]; - inline const vec3& operator [] (int i) const { return v[i]; } - inline vec3& operator [] (int i) { return v[i]; } - }; - - enum { UNKNOWN_TYPE = 0x80000000 }; - - // assumes the last row is < 0 , 0 , 1 > - vec2 transform(const vec2& v) const; - vec3 transform(const vec3& v) const; - Rect transform(const Rect& bounds) const; - uint32_t type() const; - static bool absIsOne(float f); - static bool isZero(float f); - - mat33 mMatrix; - mutable uint32_t mType; -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif /* ANDROID_TRANSFORM_H */ diff --git a/libs/surfaceflinger/clz.cpp b/libs/surfaceflinger/clz.cpp deleted file mode 100644 index 2456b86..0000000 --- a/libs/surfaceflinger/clz.cpp +++ /dev/null @@ -1,37 +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. - */ - -#include "clz.h" - -namespace android { - -int clz_impl(int32_t x) -{ -#if defined(__arm__) && !defined(__thumb__) - return __builtin_clz(x); -#else - if (!x) return 32; - int e = 31; - if (x&0xFFFF0000) { e -=16; x >>=16; } - if (x&0x0000FF00) { e -= 8; x >>= 8; } - if (x&0x000000F0) { e -= 4; x >>= 4; } - if (x&0x0000000C) { e -= 2; x >>= 2; } - if (x&0x00000002) { e -= 1; } - return e; -#endif -} - -}; // namespace android diff --git a/libs/surfaceflinger/clz.h b/libs/surfaceflinger/clz.h deleted file mode 100644 index 0ddf986..0000000 --- a/libs/surfaceflinger/clz.h +++ /dev/null @@ -1,37 +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. - */ - -#ifndef ANDROID_SURFACE_FLINGER_CLZ_H - -#include <stdint.h> - -namespace android { - -int clz_impl(int32_t x); - -int inline clz(int32_t x) -{ -#if defined(__arm__) && !defined(__thumb__) - return __builtin_clz(x); -#else - return clz_impl(x); -#endif -} - - -}; // namespace android - -#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */ diff --git a/libs/surfaceflinger/tests/Android.mk b/libs/surfaceflinger/tests/Android.mk deleted file mode 100644 index 5053e7d..0000000 --- a/libs/surfaceflinger/tests/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(call all-subdir-makefiles) diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/libs/surfaceflinger/tests/overlays/Android.mk deleted file mode 100644 index 592b601..0000000 --- a/libs/surfaceflinger/tests/overlays/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - overlays.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libui \ - libsurfaceflinger_client - -LOCAL_MODULE:= test-overlays - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/libs/surfaceflinger/tests/overlays/overlays.cpp deleted file mode 100644 index c248a615..0000000 --- a/libs/surfaceflinger/tests/overlays/overlays.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include <binder/IPCThreadState.h> -#include <binder/ProcessState.h> -#include <binder/IServiceManager.h> -#include <utils/Log.h> - -#include <ui/Overlay.h> - -#include <surfaceflinger/Surface.h> -#include <surfaceflinger/ISurface.h> -#include <surfaceflinger/SurfaceComposerClient.h> - -using namespace android; - -namespace android { -class Test { -public: - static const sp<ISurface>& getISurface(const sp<Surface>& s) { - return s->getISurface(); - } -}; -}; - -int main(int argc, char** argv) -{ - // set up the thread-pool - sp<ProcessState> proc(ProcessState::self()); - ProcessState::self()->startThreadPool(); - - // create a client to surfaceflinger - sp<SurfaceComposerClient> client = new SurfaceComposerClient(); - - // create pushbuffer surface - sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240, - PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers); - - // get to the isurface - sp<ISurface> isurface = Test::getISurface(surface); - printf("isurface = %p\n", isurface.get()); - - // now request an overlay - sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565); - sp<Overlay> overlay = new Overlay(ref); - - - /* - * here we can use the overlay API - */ - - overlay_buffer_t buffer; - overlay->dequeueBuffer(&buffer); - printf("buffer = %p\n", buffer); - - void* address = overlay->getBufferAddress(buffer); - printf("address = %p\n", address); - - overlay->queueBuffer(buffer); - - return 0; -} diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/libs/surfaceflinger/tests/resize/Android.mk deleted file mode 100644 index 24c2d01..0000000 --- a/libs/surfaceflinger/tests/resize/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - resize.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libui \ - libsurfaceflinger_client - -LOCAL_MODULE:= test-resize - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/libs/surfaceflinger/tests/resize/resize.cpp deleted file mode 100644 index 127cca3..0000000 --- a/libs/surfaceflinger/tests/resize/resize.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include <cutils/memory.h> - -#include <utils/Log.h> - -#include <binder/IPCThreadState.h> -#include <binder/ProcessState.h> -#include <binder/IServiceManager.h> - -#include <surfaceflinger/Surface.h> -#include <surfaceflinger/ISurface.h> -#include <surfaceflinger/SurfaceComposerClient.h> - -#include <ui/Overlay.h> - -using namespace android; - -namespace android { -class Test { -public: - static const sp<ISurface>& getISurface(const sp<Surface>& s) { - return s->getISurface(); - } -}; -}; - -int main(int argc, char** argv) -{ - // set up the thread-pool - sp<ProcessState> proc(ProcessState::self()); - ProcessState::self()->startThreadPool(); - - // create a client to surfaceflinger - sp<SurfaceComposerClient> client = new SurfaceComposerClient(); - - // create pushbuffer surface - sp<Surface> surface = client->createSurface(getpid(), 0, 160, 240, - PIXEL_FORMAT_RGB_565); - - - client->openTransaction(); - surface->setLayer(100000); - client->closeTransaction(); - - Surface::SurfaceInfo info; - surface->lock(&info); - ssize_t bpr = info.s * bytesPerPixel(info.format); - android_memset16((uint16_t*)info.bits, 0xF800, bpr*info.h); - surface->unlockAndPost(); - - surface->lock(&info); - android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h); - surface->unlockAndPost(); - - client->openTransaction(); - surface->setSize(320, 240); - client->closeTransaction(); - - - IPCThreadState::self()->joinThreadPool(); - - return 0; -} |