diff options
Diffstat (limited to 'services/surfaceflinger')
51 files changed, 0 insertions, 9298 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk deleted file mode 100644 index aa1e426..0000000 --- a/services/surfaceflinger/Android.mk +++ /dev/null @@ -1,56 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - EventThread.cpp \ - Layer.cpp \ - LayerBase.cpp \ - LayerDim.cpp \ - LayerScreenshot.cpp \ - DdmConnection.cpp \ - DisplayHardware/DisplayHardware.cpp \ - DisplayHardware/DisplayHardwareBase.cpp \ - DisplayHardware/HWComposer.cpp \ - DisplayHardware/VSyncBarrier.cpp \ - DisplayEventConnection.cpp \ - GLExtensions.cpp \ - MessageQueue.cpp \ - SurfaceFlinger.cpp \ - SurfaceTextureLayer.cpp \ - Transform.cpp \ - - -LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" -LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES - -ifeq ($(TARGET_HAS_WAITFORVSYNC), true) - LOCAL_CFLAGS += -DHAS_WAITFORVSYNC -endif - -ifeq ($(TARGET_BOARD_PLATFORM), omap3) - LOCAL_CFLAGS += -DNO_RGBX_8888 -endif -ifeq ($(TARGET_BOARD_PLATFORM), omap4) - LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY - LOCAL_CFLAGS += -DUSE_TRIPLE_BUFFERING -endif -ifeq ($(TARGET_BOARD_PLATFORM), s5pc110) - LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE -endif - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libhardware \ - libutils \ - libEGL \ - libGLESv1_CM \ - libbinder \ - libui \ - libgui - -# this is only needed for DDMS debugging -LOCAL_SHARED_LIBRARIES += libdvm libandroid_runtime - -LOCAL_MODULE:= libsurfaceflinger - -include $(BUILD_SHARED_LIBRARY) diff --git a/services/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h deleted file mode 100644 index 6f8507e..0000000 --- a/services/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/services/surfaceflinger/DdmConnection.cpp b/services/surfaceflinger/DdmConnection.cpp deleted file mode 100644 index 467a915..0000000 --- a/services/surfaceflinger/DdmConnection.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2011 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 <android_runtime/AndroidRuntime.h> - -#include "jni.h" -#include "DdmConnection.h" - -extern "C" jint Java_com_android_internal_util_WithFramework_registerNatives( - JNIEnv* env, jclass clazz); - -namespace android { - -void DdmConnection::start(const char* name) { - JavaVM* vm; - JNIEnv* env; - - // start a VM - JavaVMInitArgs args; - JavaVMOption opt; - - opt.optionString = - "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y"; - - args.version = JNI_VERSION_1_4; - args.options = &opt; - args.nOptions = 1; - args.ignoreUnrecognized = JNI_FALSE; - - if (JNI_CreateJavaVM(&vm, &env, &args) == 0) { - jclass startClass; - jmethodID startMeth; - - // register native code - if (Java_com_android_internal_util_WithFramework_registerNatives(env, 0) == 0) { - // set our name by calling DdmHandleAppName.setAppName() - startClass = env->FindClass("android/ddm/DdmHandleAppName"); - if (startClass) { - startMeth = env->GetStaticMethodID(startClass, - "setAppName", "(Ljava/lang/String;)V"); - if (startMeth) { - jstring str = env->NewStringUTF(name); - env->CallStaticVoidMethod(startClass, startMeth, str); - env->DeleteLocalRef(str); - } - } - - // initialize DDMS communication by calling - // DdmRegister.registerHandlers() - startClass = env->FindClass("android/ddm/DdmRegister"); - if (startClass) { - startMeth = env->GetStaticMethodID(startClass, - "registerHandlers", "()V"); - if (startMeth) { - env->CallStaticVoidMethod(startClass, startMeth); - } - } - } - } -} - -}; // namespace android diff --git a/services/surfaceflinger/DdmConnection.h b/services/surfaceflinger/DdmConnection.h deleted file mode 100644 index 91b737c..0000000 --- a/services/surfaceflinger/DdmConnection.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2011 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_DDM_CONNECTION -#define ANDROID_SF_DDM_CONNECTION - -namespace android { - -class DdmConnection { -public: - static void start(const char* name); -}; - -}; // namespace android - -#endif /* ANDROID_SF_DDM_CONNECTION */ diff --git a/services/surfaceflinger/DisplayEventConnection.cpp b/services/surfaceflinger/DisplayEventConnection.cpp deleted file mode 100644 index 77ecbd2..0000000 --- a/services/surfaceflinger/DisplayEventConnection.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 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 <sys/types.h> - -#include <gui/IDisplayEventConnection.h> -#include <gui/BitTube.h> -#include <gui/DisplayEventReceiver.h> - -#include <utils/Errors.h> - -#include "SurfaceFlinger.h" -#include "DisplayEventConnection.h" -#include "EventThread.h" - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -DisplayEventConnection::DisplayEventConnection( - const sp<EventThread>& eventThread) - : mEventThread(eventThread), mChannel(new BitTube()) -{ -} - -DisplayEventConnection::~DisplayEventConnection() { - mEventThread->unregisterDisplayEventConnection(this); -} - -void DisplayEventConnection::onFirstRef() { - // NOTE: mEventThread doesn't hold a strong reference on us - mEventThread->registerDisplayEventConnection(this); -} - -sp<BitTube> DisplayEventConnection::getDataChannel() const { - return mChannel; -} - -void DisplayEventConnection::setVsyncRate(uint32_t count) { - mEventThread->setVsyncRate(count, this); -} - -void DisplayEventConnection::requestNextVsync() { - mEventThread->requestNextVsync(this); -} - -status_t DisplayEventConnection::postEvent(const DisplayEventReceiver::Event& event) -{ - ssize_t size = mChannel->write(&event, sizeof(DisplayEventReceiver::Event)); - return size < 0 ? status_t(size) : status_t(NO_ERROR); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/DisplayEventConnection.h b/services/surfaceflinger/DisplayEventConnection.h deleted file mode 100644 index cc3ee36..0000000 --- a/services/surfaceflinger/DisplayEventConnection.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 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_DISPLAY_EVENT_CONNECTION_H -#define ANDROID_SURFACE_FLINGER_DISPLAY_EVENT_CONNECTION_H - -#include <stdint.h> -#include <sys/types.h> - -#include <gui/IDisplayEventConnection.h> - -#include <utils/Errors.h> -#include <gui/DisplayEventReceiver.h> - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -class BitTube; -class EventThread; - -// --------------------------------------------------------------------------- - -class DisplayEventConnection : public BnDisplayEventConnection { -public: - DisplayEventConnection(const sp<EventThread>& flinger); - - status_t postEvent(const DisplayEventReceiver::Event& event); - -private: - virtual ~DisplayEventConnection(); - virtual void onFirstRef(); - virtual sp<BitTube> getDataChannel() const; - virtual void setVsyncRate(uint32_t count); - virtual void requestNextVsync(); // asynchronous - - sp<EventThread> const mEventThread; - sp<BitTube> const mChannel; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif /* ANDROID_SURFACE_FLINGER_DISPLAY_EVENT_CONNECTION_H */ diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp deleted file mode 100644 index 9baae80..0000000 --- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ /dev/null @@ -1,467 +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 <GLES/gl.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include "DisplayHardware/DisplayHardware.h" - -#include <hardware/gralloc.h> - -#include "GLExtensions.h" -#include "HWComposer.h" -#include "SurfaceFlinger.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; - ALOGE("GL error 0x%04x", int(error)); - } while(true); -} - -static __attribute__((noinline)) -void checkEGLErrors(const char* token) -{ - struct EGLUtils { - static const char *strerror(EGLint err) { - switch (err){ - case EGL_SUCCESS: return "EGL_SUCCESS"; - case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; - case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; - case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; - case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; - case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; - case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; - case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; - case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; - case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; - case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; - case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; - case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; - case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; - case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; - default: return "UNKNOWN"; - } - } - }; - - EGLint error = eglGetError(); - if (error && error != EGL_SUCCESS) { - ALOGE("%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), - mFlinger(flinger), mFlags(0), mHwc(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[0] < mMaxViewportDims[1] ? - mMaxViewportDims[0] : mMaxViewportDims[1]; -} - -static status_t selectConfigForPixelFormat( - EGLDisplay dpy, - EGLint const* attrs, - PixelFormat format, - EGLConfig* outConfig) -{ - EGLConfig config = NULL; - EGLint numConfigs = -1, n=0; - eglGetConfigs(dpy, NULL, 0, &numConfigs); - EGLConfig* const configs = new EGLConfig[numConfigs]; - eglChooseConfig(dpy, attrs, configs, numConfigs, &n); - for (int i=0 ; i<n ; i++) { - EGLint nativeVisualId = 0; - eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); - if (nativeVisualId>0 && format == nativeVisualId) { - *outConfig = configs[i]; - delete [] configs; - return NO_ERROR; - } - } - delete [] configs; - return NAME_NOT_FOUND; -} - - -void DisplayHardware::init(uint32_t dpy) -{ - mNativeWindow = new FramebufferNativeWindow(); - framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); - if (!fbDev) { - ALOGE("Display subsystem failed to initialize. check logs. exiting..."); - exit(0); - } - - int format; - ANativeWindow const * const window = mNativeWindow.get(); - window->query(window, NATIVE_WINDOW_FORMAT, &format); - mDpiX = mNativeWindow->xdpi; - mDpiY = mNativeWindow->ydpi; - mRefreshRate = fbDev->fps; - mNextFakeVSync = 0; - - -/* FIXME: this is a temporary HACK until we are able to report the refresh rate - * properly from the HAL. The WindowManagerService now relies on this value. - */ -#ifndef REFRESH_RATE - mRefreshRate = fbDev->fps; -#else - mRefreshRate = REFRESH_RATE; -#warning "refresh rate set via makefile to REFRESH_RATE" -#endif - - mRefreshPeriod = nsecs_t(1e9 / mRefreshRate); - - EGLint w, h, dummy; - EGLint numConfigs=0; - EGLSurface surface; - EGLContext context; - EGLBoolean result; - status_t err; - - // 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) { - ALOGW("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 = NULL; - err = selectConfigForPixelFormat(display, attribs, format, &config); - ALOGE_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) { - ALOGW("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 - */ - - - EGLint contextAttributes[] = { -#ifdef EGL_IMG_context_priority -#ifdef HAS_CONTEXT_PRIORITY -#warning "using EGL_IMG_context_priority" - EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, -#endif -#endif - EGL_NONE, EGL_NONE - }; - context = eglCreateContext(display, config, NULL, contextAttributes); - - mDisplay = display; - mConfig = config; - mSurface = surface; - mContext = context; - mFormat = fbDev->format; - mPageFlipCount = 0; - - /* - * Gather OpenGL ES extensions - */ - - result = eglMakeCurrent(display, surface, surface, context); - if (!result) { - ALOGE("Couldn't create a working GLES context. check logs. exiting..."); - exit(0); - } - - 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); - - ALOGI("EGL informations:"); - ALOGI("# of configs : %d", numConfigs); - ALOGI("vendor : %s", extensions.getEglVendor()); - ALOGI("version : %s", extensions.getEglVersion()); - ALOGI("extensions: %s", extensions.getEglExtension()); - ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); - ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config); - - ALOGI("OpenGL informations:"); - ALOGI("vendor : %s", extensions.getVendor()); - ALOGI("renderer : %s", extensions.getRenderer()); - ALOGI("version : %s", extensions.getVersion()); - ALOGI("extensions: %s", extensions.getExtension()); - ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); - ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); - ALOGI("flags = %08x", mFlags); - - // Unbind the context from this thread - eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - - // initialize the H/W composer - mHwc = new HWComposer(mFlinger); - if (mHwc->initCheck() == NO_ERROR) { - mHwc->setFrameBuffer(mDisplay, mSurface); - } -} - -HWComposer& DisplayHardware::getHwComposer() const { - return *mHwc; -} - -/* - * 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); -} - -void DisplayHardware::releaseScreen() const -{ - DisplayHardwareBase::releaseScreen(); - if (mHwc->initCheck() == NO_ERROR) { - mHwc->release(); - } -} - -void DisplayHardware::acquireScreen() const -{ - DisplayHardwareBase::acquireScreen(); -} - -uint32_t DisplayHardware::getPageFlipCount() const { - return mPageFlipCount; -} - -// this needs to be thread safe -nsecs_t DisplayHardware::waitForRefresh() const { - nsecs_t timestamp; - if (mVSync.wait(×tamp) < 0) { - // vsync not supported! - usleep( getDelayToNextVSyncUs(×tamp) ); - } - mLastHwVSync = timestamp; // FIXME: Not thread safe - return timestamp; -} - -nsecs_t DisplayHardware::getRefreshTimestamp() const { - // this returns the last refresh timestamp. - // if the last one is not available, we estimate it based on - // the refresh period and whatever closest timestamp we have. - nsecs_t now = systemTime(); - return now - ((now - mLastHwVSync) % mRefreshPeriod); -} - -nsecs_t DisplayHardware::getRefreshPeriod() const { - return mRefreshPeriod; -} - -int32_t DisplayHardware::getDelayToNextVSyncUs(nsecs_t* timestamp) const { - Mutex::Autolock _l(mFakeVSyncMutex); - const nsecs_t period = mRefreshPeriod; - const nsecs_t now = systemTime(CLOCK_MONOTONIC); - nsecs_t next_vsync = mNextFakeVSync; - nsecs_t sleep = next_vsync - now; - if (sleep < 0) { - // we missed, find where the next vsync should be - sleep = (period - ((now - next_vsync) % period)); - next_vsync = now + sleep; - } - mNextFakeVSync = next_vsync + period; - timestamp[0] = next_vsync; - - // round to next microsecond - int32_t sleep_us = (sleep + 999LL) / 1000LL; - - // guaranteed to be > 0 - return sleep_us; -} - -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++; - - if (mHwc->initCheck() == NO_ERROR) { - mHwc->commit(); - } else { - 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); -} - -void DisplayHardware::dump(String8& res) const -{ - mNativeWindow->dump(res); -} diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h deleted file mode 100644 index 0a828b3..0000000 --- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h +++ /dev/null @@ -1,131 +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 "GLExtensions.h" - -#include "DisplayHardware/DisplayHardwareBase.h" -#include "DisplayHardware/VSyncBarrier.h" - -namespace android { - -class FramebufferNativeWindow; -class HWComposer; - -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; - - // waits for the next vsync and returns the timestamp of when it happened - nsecs_t waitForRefresh() const; - nsecs_t getRefreshPeriod() const; - nsecs_t getRefreshTimestamp() const; - - uint32_t getPageFlipCount() const; - EGLDisplay getEGLDisplay() const { return mDisplay; } - - void dump(String8& res) const; - - // Hardware Composer - HWComposer& getHwComposer() const; - - status_t compositionComplete() const; - - Rect getBounds() const { - return Rect(mWidth, mHeight); - } - inline Rect bounds() const { return getBounds(); } - -private: - void init(uint32_t displayIndex) __attribute__((noinline)); - void fini() __attribute__((noinline)); - int32_t getDelayToNextVSyncUs(nsecs_t* timestamp) const; - - sp<SurfaceFlinger> mFlinger; - 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[2]; - GLint mMaxTextureSize; - VSyncBarrier mVSync; - - mutable Mutex mFakeVSyncMutex; - mutable nsecs_t mNextFakeVSync; - nsecs_t mRefreshPeriod; - mutable nsecs_t mLastHwVSync; - - HWComposer* mHwc; - - sp<FramebufferNativeWindow> mNativeWindow; -}; - -}; // namespace android - -#endif // ANDROID_DISPLAY_HARDWARE_H diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp deleted file mode 100644 index 69f1aca..0000000 --- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2012 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 <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <unistd.h> -#include <fcntl.h> - -#include <utils/Log.h> - -#include "DisplayHardware/DisplayHardwareBase.h" -#include "SurfaceFlinger.h" - -// ---------------------------------------------------------------------------- -namespace android { - -static char const * const kSleepFileName = "/sys/power/wait_for_fb_sleep"; -static char const * const kWakeFileName = "/sys/power/wait_for_fb_wake"; - -// ---------------------------------------------------------------------------- - -DisplayHardwareBase::DisplayEventThread::DisplayEventThread( - const sp<SurfaceFlinger>& flinger) - : Thread(false), mFlinger(flinger) { -} - -DisplayHardwareBase::DisplayEventThread::~DisplayEventThread() { -} - -status_t DisplayHardwareBase::DisplayEventThread::initCheck() const { - return ((access(kSleepFileName, R_OK) == 0 && - access(kWakeFileName, R_OK) == 0)) ? NO_ERROR : NO_INIT; -} - -bool DisplayHardwareBase::DisplayEventThread::threadLoop() { - - if (waitForFbSleep() == NO_ERROR) { - sp<SurfaceFlinger> flinger = mFlinger.promote(); - ALOGD("About to give-up screen, flinger = %p", flinger.get()); - if (flinger != 0) { - mBarrier.close(); - flinger->screenReleased(0); - mBarrier.wait(); - } - if (waitForFbWake() == NO_ERROR) { - sp<SurfaceFlinger> flinger = mFlinger.promote(); - ALOGD("Screen about to return, flinger = %p", flinger.get()); - if (flinger != 0) { - flinger->screenAcquired(0); - } - return true; - } - } - - // error, exit the thread - return false; -} - -status_t DisplayHardwareBase::DisplayEventThread::waitForFbSleep() { - int err = 0; - char buf; - int fd = open(kSleepFileName, O_RDONLY, 0); - // if the file doesn't exist, the error will be caught in read() below - do { - err = read(fd, &buf, 1); - } while (err < 0 && errno == EINTR); - close(fd); - ALOGE_IF(err<0, "*** ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno)); - return err < 0 ? -errno : int(NO_ERROR); -} - -status_t DisplayHardwareBase::DisplayEventThread::waitForFbWake() { - int err = 0; - char buf; - int fd = open(kWakeFileName, O_RDONLY, 0); - // if the file doesn't exist, the error will be caught in read() below - do { - err = read(fd, &buf, 1); - } while (err < 0 && errno == EINTR); - close(fd); - ALOGE_IF(err<0, "*** ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno)); - return err < 0 ? -errno : int(NO_ERROR); -} - -status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const { - mBarrier.open(); - return NO_ERROR; -} - -// ---------------------------------------------------------------------------- - -DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger, - uint32_t displayIndex) - : mScreenAcquired(true) -{ - mDisplayEventThread = new DisplayEventThread(flinger); -} - -void DisplayHardwareBase::startSleepManagement() const { - if (mDisplayEventThread->initCheck() == NO_ERROR) { - mDisplayEventThread->run("DisplayEventThread", PRIORITY_URGENT_DISPLAY); - } else { - ALOGW("/sys/power/wait_for_fb_{wake|sleep} don't exist"); - } -} - -DisplayHardwareBase::~DisplayHardwareBase() { - // request exit - mDisplayEventThread->requestExitAndWait(); -} - -bool DisplayHardwareBase::canDraw() const { - return mScreenAcquired; -} - -void DisplayHardwareBase::releaseScreen() const { - status_t err = mDisplayEventThread->releaseScreen(); - if (err >= 0) { - mScreenAcquired = false; - } -} - -void DisplayHardwareBase::acquireScreen() const { - mScreenAcquired = true; -} - -bool DisplayHardwareBase::isScreenAcquired() const { - return mScreenAcquired; -} - -}; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h deleted file mode 100644 index fba211b..0000000 --- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2012 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 "Barrier.h" - -namespace android { - -class SurfaceFlinger; - -class DisplayHardwareBase -{ -public: - DisplayHardwareBase( - const sp<SurfaceFlinger>& flinger, - uint32_t displayIndex); - - ~DisplayHardwareBase(); - - void startSleepManagement() const; - - // console management - void releaseScreen() const; - void acquireScreen() const; - bool isScreenAcquired() const; - - bool canDraw() const; - - -private: - class DisplayEventThread : public Thread { - wp<SurfaceFlinger> mFlinger; - mutable Barrier mBarrier; - status_t waitForFbSleep(); - status_t waitForFbWake(); - public: - DisplayEventThread(const sp<SurfaceFlinger>& flinger); - virtual ~DisplayEventThread(); - virtual bool threadLoop(); - status_t releaseScreen() const; - status_t initCheck() const; - }; - - sp<DisplayEventThread> mDisplayEventThread; - mutable int mScreenAcquired; -}; - -}; // namespace android - -#endif // ANDROID_DISPLAY_HARDWARE_BASE_H diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp deleted file mode 100644 index f17bf43..0000000 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ /dev/null @@ -1,209 +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 <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/String8.h> -#include <utils/Vector.h> - -#include <hardware/hardware.h> - -#include <cutils/log.h> - -#include <EGL/egl.h> - -#include "LayerBase.h" -#include "HWComposer.h" -#include "SurfaceFlinger.h" - -namespace android { -// --------------------------------------------------------------------------- - -HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) - : mFlinger(flinger), - mModule(0), mHwc(0), mList(0), mCapacity(0), - mNumOVLayers(0), mNumFBLayers(0), - mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE) -{ - int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); - ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); - if (err == 0) { - err = hwc_open(mModule, &mHwc); - ALOGE_IF(err, "%s device failed to initialize (%s)", - HWC_HARDWARE_COMPOSER, strerror(-err)); - if (err == 0) { - if (mHwc->registerProcs) { - mCBContext.hwc = this; - mCBContext.procs.invalidate = &hook_invalidate; - mHwc->registerProcs(mHwc, &mCBContext.procs); - } - } - } -} - -HWComposer::~HWComposer() { - free(mList); - if (mHwc) { - hwc_close(mHwc); - } -} - -status_t HWComposer::initCheck() const { - return mHwc ? NO_ERROR : NO_INIT; -} - -void HWComposer::hook_invalidate(struct hwc_procs* procs) { - reinterpret_cast<cb_context *>(procs)->hwc->invalidate(); -} - -void HWComposer::invalidate() { - mFlinger->repaintEverything(); -} - -void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) { - mDpy = (hwc_display_t)dpy; - mSur = (hwc_surface_t)sur; -} - -status_t HWComposer::createWorkList(size_t numLayers) { - if (mHwc) { - if (!mList || mCapacity < numLayers) { - free(mList); - size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); - mList = (hwc_layer_list_t*)malloc(size); - mCapacity = numLayers; - } - mList->flags = HWC_GEOMETRY_CHANGED; - mList->numHwLayers = numLayers; - } - return NO_ERROR; -} - -status_t HWComposer::prepare() const { - int err = mHwc->prepare(mHwc, mList); - if (err == NO_ERROR) { - size_t numOVLayers = 0; - size_t numFBLayers = 0; - size_t count = mList->numHwLayers; - for (size_t i=0 ; i<count ; i++) { - hwc_layer& l(mList->hwLayers[i]); - if (l.flags & HWC_SKIP_LAYER) { - l.compositionType = HWC_FRAMEBUFFER; - } - switch (l.compositionType) { - case HWC_OVERLAY: - numOVLayers++; - break; - case HWC_FRAMEBUFFER: - numFBLayers++; - break; - } - } - mNumOVLayers = numOVLayers; - mNumFBLayers = numFBLayers; - } - return (status_t)err; -} - -size_t HWComposer::getLayerCount(int type) const { - switch (type) { - case HWC_OVERLAY: - return mNumOVLayers; - case HWC_FRAMEBUFFER: - return mNumFBLayers; - } - return 0; -} - -status_t HWComposer::commit() const { - int err = mHwc->set(mHwc, mDpy, mSur, mList); - if (mList) { - mList->flags &= ~HWC_GEOMETRY_CHANGED; - } - return (status_t)err; -} - -status_t HWComposer::release() const { - if (mHwc) { - int err = mHwc->set(mHwc, NULL, NULL, NULL); - return (status_t)err; - } - return NO_ERROR; -} - -status_t HWComposer::disable() { - if (mHwc) { - free(mList); - mList = NULL; - int err = mHwc->prepare(mHwc, NULL); - return (status_t)err; - } - return NO_ERROR; -} - -size_t HWComposer::getNumLayers() const { - return mList ? mList->numHwLayers : 0; -} - -hwc_layer_t* HWComposer::getLayers() const { - return mList ? mList->hwLayers : 0; -} - -void HWComposer::dump(String8& result, char* buffer, size_t SIZE, - const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { - if (mHwc && mList) { - result.append("Hardware Composer state:\n"); - - snprintf(buffer, SIZE, " numHwLayers=%u, flags=%08x\n", - mList->numHwLayers, mList->flags); - result.append(buffer); - result.append( - " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" - "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); - // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] - for (size_t i=0 ; i<mList->numHwLayers ; i++) { - const hwc_layer_t& l(mList->hwLayers[i]); - const sp<LayerBase> layer(visibleLayersSortedByZ[i]); - int32_t format = -1; - if (layer->getLayer() != NULL) { - const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); - if (buffer != NULL) { - format = buffer->getPixelFormat(); - } - } - snprintf(buffer, SIZE, - " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", - l.compositionType ? "OVERLAY" : "FB", - intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, - l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, - l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, - layer->getName().string()); - result.append(buffer); - } - } - if (mHwc && mHwc->common.version >= 1 && mHwc->dump) { - mHwc->dump(mHwc, buffer, SIZE); - result.append(buffer); - } -} - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h deleted file mode 100644 index aa8ebe1..0000000 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ /dev/null @@ -1,98 +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_HWCOMPOSER_H -#define ANDROID_SF_HWCOMPOSER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> - -#include <hardware/hwcomposer.h> - -#include <utils/StrongPointer.h> -#include <utils/Vector.h> - -namespace android { -// --------------------------------------------------------------------------- - -class String8; -class SurfaceFlinger; -class LayerBase; - -class HWComposer -{ -public: - - HWComposer(const sp<SurfaceFlinger>& flinger); - ~HWComposer(); - - status_t initCheck() const; - - // tells the HAL what the framebuffer is - void setFrameBuffer(EGLDisplay dpy, EGLSurface sur); - - // create a work list for numLayers layer - status_t createWorkList(size_t numLayers); - - // Asks the HAL what it can do - status_t prepare() const; - - // disable hwc until next createWorkList - status_t disable(); - - // commits the list - status_t commit() const; - - // release hardware resources - status_t release() const; - - size_t getNumLayers() const; - hwc_layer_t* getLayers() const; - - // updated in preapre() - size_t getLayerCount(int type) const; - - // for debugging - void dump(String8& out, char* scratch, size_t SIZE, - const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; - -private: - struct cb_context { - hwc_procs_t procs; - HWComposer* hwc; - }; - static void hook_invalidate(struct hwc_procs* procs); - void invalidate(); - - sp<SurfaceFlinger> mFlinger; - hw_module_t const* mModule; - hwc_composer_device_t* mHwc; - hwc_layer_list_t* mList; - size_t mCapacity; - mutable size_t mNumOVLayers; - mutable size_t mNumFBLayers; - hwc_display_t mDpy; - hwc_surface_t mSur; - cb_context mCBContext; -}; - - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SF_HWCOMPOSER_H diff --git a/services/surfaceflinger/DisplayHardware/VSyncBarrier.cpp b/services/surfaceflinger/DisplayHardware/VSyncBarrier.cpp deleted file mode 100644 index 187da20..0000000 --- a/services/surfaceflinger/DisplayHardware/VSyncBarrier.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2011 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 <sys/types.h> - -#include <utils/Errors.h> - -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/fb.h> - -#include "DisplayHardware/VSyncBarrier.h" - -#ifndef FBIO_WAITFORVSYNC -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -#endif - -namespace android { -// --------------------------------------------------------------------------- - -VSyncBarrier::VSyncBarrier() : mFd(-EINVAL) { -#if HAS_WAITFORVSYNC - mFd = open("/dev/graphics/fb0", O_RDWR); - if (mFd < 0) { - mFd = -errno; - } - // try to see if FBIO_WAITFORVSYNC is supported - uint32_t crt = 0; - int err = ioctl(mFd, FBIO_WAITFORVSYNC, &crt); - if (err < 0) { - close(mFd); - mFd = -EINVAL; - } -#endif -} - -VSyncBarrier::~VSyncBarrier() { - if (mFd >= 0) { - close(mFd); - } -} - -status_t VSyncBarrier::initCheck() const { - return mFd < 0 ? mFd : status_t(NO_ERROR); -} - -// this must be thread-safe -status_t VSyncBarrier::wait(nsecs_t* timestamp) const { - if (mFd < 0) { - return mFd; - } - - int err; - uint32_t crt = 0; - do { - err = ioctl(mFd, FBIO_WAITFORVSYNC, &crt); - } while (err<0 && errno==EINTR); - if (err < 0) { - return -errno; - } - // ideally this would come from the driver - timestamp[0] = systemTime(); - return NO_ERROR; -} - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/VSyncBarrier.h b/services/surfaceflinger/DisplayHardware/VSyncBarrier.h deleted file mode 100644 index 3c32950..0000000 --- a/services/surfaceflinger/DisplayHardware/VSyncBarrier.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2011 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_VSYNCBARRIER_H_ -#define ANDROID_SURFACE_FLINGER_VSYNCBARRIER_H_ - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/Timers.h> - -namespace android { -// --------------------------------------------------------------------------- - -class VSyncBarrier { - int mFd; -public: - VSyncBarrier(); - ~VSyncBarrier(); - status_t initCheck() const; - status_t wait(nsecs_t* timestamp) const; -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif /* ANDROID_SURFACE_FLINGER_VSYNCBARRIER_H_ */ diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp deleted file mode 100644 index 3c045d7..0000000 --- a/services/surfaceflinger/EventThread.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS - -#include <stdint.h> -#include <sys/types.h> - -#include <gui/IDisplayEventConnection.h> -#include <gui/DisplayEventReceiver.h> - -#include <utils/Errors.h> -#include <utils/Trace.h> - -#include "DisplayHardware/DisplayHardware.h" -#include "DisplayEventConnection.h" -#include "EventThread.h" -#include "SurfaceFlinger.h" - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -EventThread::EventThread(const sp<SurfaceFlinger>& flinger) - : mFlinger(flinger), - mHw(flinger->graphicPlane(0).displayHardware()), - mLastVSyncTimestamp(0), - mDeliveredEvents(0) -{ -} - -void EventThread::onFirstRef() { - run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); -} - -sp<DisplayEventConnection> EventThread::createEventConnection() const { - return new DisplayEventConnection(const_cast<EventThread*>(this)); -} - -nsecs_t EventThread::getLastVSyncTimestamp() const { - Mutex::Autolock _l(mLock); - return mLastVSyncTimestamp; -} - -nsecs_t EventThread::getVSyncPeriod() const { - return mHw.getRefreshPeriod(); - -} - -status_t EventThread::registerDisplayEventConnection( - const sp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - ConnectionInfo info; - mDisplayEventConnections.add(connection, info); - mCondition.signal(); - return NO_ERROR; -} - -status_t EventThread::unregisterDisplayEventConnection( - const wp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - mDisplayEventConnections.removeItem(connection); - mCondition.signal(); - return NO_ERROR; -} - -void EventThread::removeDisplayEventConnection( - const wp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - mDisplayEventConnections.removeItem(connection); -} - -EventThread::ConnectionInfo* EventThread::getConnectionInfoLocked( - const wp<DisplayEventConnection>& connection) { - ssize_t index = mDisplayEventConnections.indexOfKey(connection); - if (index < 0) return NULL; - return &mDisplayEventConnections.editValueAt(index); -} - -void EventThread::setVsyncRate(uint32_t count, - const wp<DisplayEventConnection>& connection) { - if (int32_t(count) >= 0) { // server must protect against bad params - Mutex::Autolock _l(mLock); - ConnectionInfo* info = getConnectionInfoLocked(connection); - if (info) { - const int32_t new_count = (count == 0) ? -1 : count; - if (info->count != new_count) { - info->count = new_count; - mCondition.signal(); - } - } - } -} - -void EventThread::requestNextVsync( - const wp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - ConnectionInfo* info = getConnectionInfoLocked(connection); - if (info && info->count < 0) { - info->count = 0; - mCondition.signal(); - } -} - -bool EventThread::threadLoop() { - - nsecs_t timestamp; - DisplayEventReceiver::Event vsync; - Vector< wp<DisplayEventConnection> > displayEventConnections; - - { // scope for the lock - Mutex::Autolock _l(mLock); - do { - // see if we need to wait for the VSYNC at all - do { - bool waitForNextVsync = false; - size_t count = mDisplayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - const ConnectionInfo& info( - mDisplayEventConnections.valueAt(i)); - if (info.count >= 0) { - // at least one continuous mode or active one-shot event - waitForNextVsync = true; - break; - } - } - - if (waitForNextVsync) - break; - - mCondition.wait(mLock); - } while(true); - - // at least one listener requested VSYNC - mLock.unlock(); - timestamp = mHw.waitForRefresh(); - ATRACE_INT("VSYNC", mDeliveredEvents&1); - mLock.lock(); - mDeliveredEvents++; - mLastVSyncTimestamp = timestamp; - - // now see if we still need to report this VSYNC event - const size_t count = mDisplayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - bool reportVsync = false; - const ConnectionInfo& info( - mDisplayEventConnections.valueAt(i)); - if (info.count >= 1) { - if (info.count==1 || (mDeliveredEvents % info.count) == 0) { - // continuous event, and time to report it - reportVsync = true; - } - } else if (info.count >= -1) { - ConnectionInfo& info( - mDisplayEventConnections.editValueAt(i)); - if (info.count == 0) { - // fired this time around - reportVsync = true; - } - info.count--; - } - if (reportVsync) { - displayEventConnections.add(mDisplayEventConnections.keyAt(i)); - } - } - } while (!displayEventConnections.size()); - - // dispatch vsync events to listeners... - vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - vsync.header.timestamp = timestamp; - vsync.vsync.count = mDeliveredEvents; - } - - const size_t count = displayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - sp<DisplayEventConnection> conn(displayEventConnections[i].promote()); - // make sure the connection didn't die - if (conn != NULL) { - status_t err = conn->postEvent(vsync); - if (err == -EAGAIN || err == -EWOULDBLOCK) { - // The destination doesn't accept events anymore, it's probably - // full. For now, we just drop the events on the floor. - // Note that some events cannot be dropped and would have to be - // re-sent later. Right-now we don't have the ability to do - // this, but it doesn't matter for VSYNC. - } else if (err < 0) { - // handle any other error on the pipe as fatal. the only - // reasonable thing to do is to clean-up this connection. - // The most common error we'll get here is -EPIPE. - removeDisplayEventConnection(displayEventConnections[i]); - } - } else { - // somehow the connection is dead, but we still have it in our list - // just clean the list. - removeDisplayEventConnection(displayEventConnections[i]); - } - } - - // clear all our references without holding mLock - displayEventConnections.clear(); - - return true; -} - -status_t EventThread::readyToRun() { - ALOGI("EventThread ready to run."); - return NO_ERROR; -} - -void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { - Mutex::Autolock _l(mLock); - result.append("VSYNC state:\n"); - snprintf(buffer, SIZE, " numListeners=%u, events-delivered: %u\n", - mDisplayEventConnections.size(), mDeliveredEvents); - result.append(buffer); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h deleted file mode 100644 index 3a3071e..0000000 --- a/services/surfaceflinger/EventThread.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2011 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_EVENT_THREAD_H -#define ANDROID_SURFACE_FLINGER_EVENT_THREAD_H - -#include <stdint.h> -#include <sys/types.h> - -#include <gui/IDisplayEventConnection.h> - -#include <utils/Errors.h> -#include <utils/threads.h> -#include <utils/KeyedVector.h> - -#include "DisplayEventConnection.h" - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -class SurfaceFlinger; -class DisplayHardware; -class DisplayEventConnection; - -// --------------------------------------------------------------------------- - -class EventThread : public Thread { - friend class DisplayEventConnection; - -public: - EventThread(const sp<SurfaceFlinger>& flinger); - - sp<DisplayEventConnection> createEventConnection() const; - - status_t registerDisplayEventConnection( - const sp<DisplayEventConnection>& connection); - - status_t unregisterDisplayEventConnection( - const wp<DisplayEventConnection>& connection); - - void setVsyncRate(uint32_t count, - const wp<DisplayEventConnection>& connection); - - void requestNextVsync(const wp<DisplayEventConnection>& connection); - - nsecs_t getLastVSyncTimestamp() const; - - nsecs_t getVSyncPeriod() const; - - void dump(String8& result, char* buffer, size_t SIZE) const; - -private: - virtual bool threadLoop(); - virtual status_t readyToRun(); - virtual void onFirstRef(); - - struct ConnectionInfo { - ConnectionInfo() : count(-1) { } - - // count >= 1 : continuous event. count is the vsync rate - // count == 0 : one-shot event that has not fired - // count ==-1 : one-shot event that fired this round / disabled - // count ==-2 : one-shot event that fired the round before - int32_t count; - }; - - void removeDisplayEventConnection( - const wp<DisplayEventConnection>& connection); - - ConnectionInfo* getConnectionInfoLocked( - const wp<DisplayEventConnection>& connection); - - // constants - sp<SurfaceFlinger> mFlinger; - const DisplayHardware& mHw; - - mutable Mutex mLock; - mutable Condition mCondition; - - // protected by mLock - KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > mDisplayEventConnections; - nsecs_t mLastVSyncTimestamp; - - // main thread only - size_t mDeliveredEvents; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif /* ANDROID_SURFACE_FLINGER_EVENT_THREAD_H */ diff --git a/services/surfaceflinger/GLExtensions.cpp b/services/surfaceflinger/GLExtensions.cpp deleted file mode 100644 index 493122d..0000000 --- a/services/surfaceflinger/GLExtensions.cpp +++ /dev/null @@ -1,137 +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_EGL_image_external")) { - mHaveTextureExternal = true; - } else if (strstr(mRenderer.string(), "Adreno")) { - // hack for Adreno 200 - mHaveTextureExternal = true; - } - - if (hasExtension("GL_OES_framebuffer_object")) { - mHaveFramebufferObject = 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/services/surfaceflinger/GLExtensions.h b/services/surfaceflinger/GLExtensions.h deleted file mode 100644 index c86c66a..0000000 --- a/services/surfaceflinger/GLExtensions.h +++ /dev/null @@ -1,99 +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; - bool mHaveFramebufferObject : 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; - } - - inline bool haveFramebufferObject() const { - return mHaveFramebufferObject; - } - - 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/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp deleted file mode 100644 index df7fe5c..0000000 --- a/services/surfaceflinger/Layer.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> -#include <math.h> - -#include <cutils/compiler.h> -#include <cutils/native_handle.h> -#include <cutils/properties.h> - -#include <utils/Errors.h> -#include <utils/Log.h> -#include <utils/StopWatch.h> -#include <utils/Trace.h> - -#include <ui/GraphicBuffer.h> -#include <ui/PixelFormat.h> - -#include <gui/Surface.h> - -#include "clz.h" -#include "DisplayHardware/DisplayHardware.h" -#include "DisplayHardware/HWComposer.h" -#include "GLExtensions.h" -#include "Layer.h" -#include "SurfaceFlinger.h" -#include "SurfaceTextureLayer.h" - -#define DEBUG_RESIZE 0 - -namespace android { - -// --------------------------------------------------------------------------- - -Layer::Layer(SurfaceFlinger* flinger, - DisplayID display, const sp<Client>& client) - : LayerBaseClient(flinger, display, client), - mTextureName(-1U), - mQueuedFrames(0), - mCurrentTransform(0), - mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), - mCurrentOpacity(true), - mRefreshPending(false), - mFrameLatencyNeeded(false), - mFrameLatencyOffset(0), - mFormat(PIXEL_FORMAT_NONE), - mGLExtensions(GLExtensions::getInstance()), - mOpaqueLayer(true), - mNeedsDithering(false), - mSecure(false), - mProtectedByApp(false) -{ - mCurrentCrop.makeInvalid(); - glGenTextures(1, &mTextureName); -} - -void Layer::onLayerDisplayed() { - if (mFrameLatencyNeeded) { - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp(); - mFrameStats[mFrameLatencyOffset].set = systemTime(); - mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp(); - mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; - mFrameLatencyNeeded = false; - } -} - -void Layer::onFirstRef() -{ - LayerBaseClient::onFirstRef(); - - struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { - FrameQueuedListener(Layer* layer) : mLayer(layer) { } - private: - wp<Layer> mLayer; - virtual void onFrameAvailable() { - sp<Layer> that(mLayer.promote()); - if (that != 0) { - that->onFrameQueued(); - } - } - }; - mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); - mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); - mSurfaceTexture->setSynchronousMode(true); -#ifdef USE_TRIPLE_BUFFERING -#warning "using triple buffering" - mSurfaceTexture->setBufferCountServer(3); -#else - mSurfaceTexture->setBufferCountServer(2); -#endif -} - -Layer::~Layer() -{ - mFlinger->postMessageAsync( - new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); -} - -void Layer::onFrameQueued() { - android_atomic_inc(&mQueuedFrames); - mFlinger->signalLayerUpdate(); -} - -// called with SurfaceFlinger::mStateLock as soon as the layer is entered -// in the purgatory list -void Layer::onRemoved() -{ - mSurfaceTexture->abandon(); -} - -void Layer::setName(const String8& name) { - LayerBase::setName(name); - mSurfaceTexture->setName(name); -} - -sp<ISurface> Layer::createSurface() -{ - class BSurface : public BnSurface, public LayerCleaner { - wp<const Layer> mOwner; - virtual sp<ISurfaceTexture> getSurfaceTexture() const { - sp<ISurfaceTexture> res; - sp<const Layer> that( mOwner.promote() ); - if (that != NULL) { - res = that->mSurfaceTexture; - } - return res; - } - public: - BSurface(const sp<SurfaceFlinger>& flinger, - const sp<Layer>& layer) - : LayerCleaner(flinger, layer), mOwner(layer) { } - }; - sp<ISurface> sur(new BSurface(mFlinger, this)); - return sur; -} - -wp<IBinder> Layer::getSurfaceTextureBinder() const -{ - return mSurfaceTexture->asBinder(); -} - -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) { - ALOGE("unsupported pixelformat %d", format); - 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)) { - ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); - return BAD_VALUE; - } - - PixelFormatInfo displayInfo; - getPixelFormatInfo(hw.getFormat(), &displayInfo); - const uint32_t hwFlags = hw.getFlags(); - - mFormat = format; - - mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; - mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; - mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); - mCurrentOpacity = getOpacityForFormat(format); - - mSurfaceTexture->setDefaultBufferSize(w, h); - mSurfaceTexture->setDefaultBufferFormat(format); - - // we use the red index - int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); - int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); - mNeedsDithering = layerRedsize > displayRedSize; - - return NO_ERROR; -} - -void Layer::setGeometry(hwc_layer_t* hwcl) -{ - LayerBaseClient::setGeometry(hwcl); - - hwcl->flags &= ~HWC_SKIP_LAYER; - - // we can't do alpha-fade with the hwc HAL - const State& s(drawingState()); - if (s.alpha < 0xFF) { - hwcl->flags = HWC_SKIP_LAYER; - } - - /* - * Transformations are applied in this order: - * 1) buffer orientation/flip/mirror - * 2) state transformation (window manager) - * 3) layer orientation (screen orientation) - * mTransform is already the composition of (2) and (3) - * (NOTE: the matrices are multiplied in reverse order) - */ - - const Transform bufferOrientation(mCurrentTransform); - const Transform tr(mTransform * bufferOrientation); - - // this gives us only the "orientation" component of the transform - const uint32_t finalTransform = tr.getOrientation(); - - // we can only handle simple transformation - if (finalTransform & Transform::ROT_INVALID) { - hwcl->flags = HWC_SKIP_LAYER; - } else { - hwcl->transform = finalTransform; - } - - if (isCropped()) { - hwcl->sourceCrop.left = mCurrentCrop.left; - hwcl->sourceCrop.top = mCurrentCrop.top; - hwcl->sourceCrop.right = mCurrentCrop.right; - hwcl->sourceCrop.bottom = mCurrentCrop.bottom; - } else { - const sp<GraphicBuffer>& buffer(mActiveBuffer); - hwcl->sourceCrop.left = 0; - hwcl->sourceCrop.top = 0; - if (buffer != NULL) { - hwcl->sourceCrop.right = buffer->width; - hwcl->sourceCrop.bottom = buffer->height; - } else { - hwcl->sourceCrop.right = mTransformedBounds.width(); - hwcl->sourceCrop.bottom = mTransformedBounds.height(); - } - } -} - -void Layer::setPerFrameData(hwc_layer_t* hwcl) { - const sp<GraphicBuffer>& buffer(mActiveBuffer); - if (buffer == NULL) { - // this can happen if the client never drew into this layer yet, - // or if we ran out of memory. In that case, don't let - // HWC handle it. - hwcl->flags |= HWC_SKIP_LAYER; - hwcl->handle = NULL; - } else { - hwcl->handle = buffer->handle; - } -} - -void Layer::onDraw(const Region& clip) const -{ - ATRACE_CALL(); - - if (CC_UNLIKELY(mActiveBuffer == 0)) { - // 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; - } - - if (!isProtected()) { - glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); - GLenum filter = GL_NEAREST; - if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) { - // TODO: we could be more subtle with isFixedSize() - filter = GL_LINEAR; - } - glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); - glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(mTextureMatrix); - glMatrixMode(GL_MODELVIEW); - glDisable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_EXTERNAL_OES); - } else { - glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glDisable(GL_TEXTURE_EXTERNAL_OES); - glEnable(GL_TEXTURE_2D); - } - - drawWithOpenGL(clip); - - glDisable(GL_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); -} - -// As documented in libhardware header, formats in the range -// 0x100 - 0x1FF are specific to the HAL implementation, and -// are known to have no alpha channel -// TODO: move definition for device-specific range into -// hardware.h, instead of using hard-coded values here. -#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) - -bool Layer::getOpacityForFormat(uint32_t format) -{ - if (HARDWARE_IS_DEVICE_FORMAT(format)) { - return true; - } - PixelFormatInfo info; - status_t err = getPixelFormatInfo(PixelFormat(format), &info); - // in case of error (unknown format), we assume no blending - return (err || info.h_alpha <= info.l_alpha); -} - - -bool Layer::isOpaque() const -{ - // if we don't have a buffer yet, we're translucent regardless of the - // layer's opaque flag. - if (mActiveBuffer == 0) { - return false; - } - - // if the layer has the opaque flag, then we're always opaque, - // otherwise we use the current buffer's format. - return mOpaqueLayer || mCurrentOpacity; -} - -bool Layer::isProtected() const -{ - const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); - return (activeBuffer != 0) && - (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); -} - -uint32_t Layer::doTransaction(uint32_t flags) -{ - ATRACE_CALL(); - - 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 - ALOGD_IF(DEBUG_RESIZE, - "doTransaction: " - "resize (layer=%p), requested (%dx%d), drawing (%d,%d), " - "scalingMode=%d", - this, - int(temp.requested_w), int(temp.requested_h), - int(front.requested_w), int(front.requested_h), - mCurrentScalingMode); - - if (!isFixedSize()) { - // 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. - mSurfaceTexture->setDefaultBufferSize(temp.requested_w, - temp.requested_h); - } - - return LayerBase::doTransaction(flags); -} - -bool Layer::isFixedSize() const { - return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; -} - -bool Layer::isCropped() const { - return !mCurrentCrop.isEmpty(); -} - -// ---------------------------------------------------------------------------- -// pageflip handling... -// ---------------------------------------------------------------------------- - -bool Layer::onPreComposition() { - mRefreshPending = false; - return mQueuedFrames > 0; -} - -void Layer::lockPageFlip(bool& recomputeVisibleRegions) -{ - ATRACE_CALL(); - - if (mQueuedFrames > 0) { - - // if we've already called updateTexImage() without going through - // a composition step, we have to skip this layer at this point - // because we cannot call updateTeximage() without a corresponding - // compositionComplete() call. - // we'll trigger an update in onPreComposition(). - if (mRefreshPending) { - mPostedDirtyRegion.clear(); - return; - } - mRefreshPending = true; - - // Capture the old state of the layer for comparisons later - const bool oldOpacity = isOpaque(); - sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; - - // signal another event if we have more frames pending - if (android_atomic_dec(&mQueuedFrames) > 1) { - mFlinger->signalLayerUpdate(); - } - - if (mSurfaceTexture->updateTexImage() < NO_ERROR) { - // something happened! - recomputeVisibleRegions = true; - return; - } - - // update the active buffer - mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); - mFrameLatencyNeeded = true; - - if (oldActiveBuffer == NULL && mActiveBuffer != NULL) { - // the first time we receive a buffer, we need to trigger a - // geometry invalidation. - mFlinger->invalidateHwcGeometry(); - } - - const Rect crop(mSurfaceTexture->getCurrentCrop()); - const uint32_t transform(mSurfaceTexture->getCurrentTransform()); - const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); - if ((crop != mCurrentCrop) || - (transform != mCurrentTransform) || - (scalingMode != mCurrentScalingMode)) - { - mCurrentCrop = crop; - mCurrentTransform = transform; - mCurrentScalingMode = scalingMode; - mFlinger->invalidateHwcGeometry(); - } - - GLfloat textureMatrix[16]; - mSurfaceTexture->getTransformMatrix(textureMatrix); - if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) { - memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix)); - mFlinger->invalidateHwcGeometry(); - } - - uint32_t bufWidth = mActiveBuffer->getWidth(); - uint32_t bufHeight = mActiveBuffer->getHeight(); - if (oldActiveBuffer != NULL) { - if (bufWidth != uint32_t(oldActiveBuffer->width) || - bufHeight != uint32_t(oldActiveBuffer->height)) { - mFlinger->invalidateHwcGeometry(); - } - } - - mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); - if (oldOpacity != isOpaque()) { - recomputeVisibleRegions = true; - } - - glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // update the layer size if needed - const Layer::State& front(drawingState()); - - // FIXME: mPostedDirtyRegion = dirty & bounds - mPostedDirtyRegion.set(front.w, front.h); - - if ((front.w != front.requested_w) || - (front.h != front.requested_h)) - { - // check that we received a buffer of the right size - // (Take the buffer's orientation into account) - if (mCurrentTransform & Transform::ROT_90) { - swap(bufWidth, bufHeight); - } - - if (isFixedSize() || - (bufWidth == front.requested_w && - bufHeight == 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; - } - - ALOGD_IF(DEBUG_RESIZE, - "lockPageFlip : " - " (layer=%p), buffer (%ux%u, tr=%02x), " - "requested (%dx%d)", - this, - bufWidth, bufHeight, mCurrentTransform, - front.requested_w, front.requested_h); - } - } -} - -void Layer::unlockPageFlip( - const Transform& planeTransform, Region& outDirtyRegion) -{ - ATRACE_CALL(); - - Region postedRegion(mPostedDirtyRegion); - if (!postedRegion.isEmpty()) { - mPostedDirtyRegion.clear(); - if (!visibleRegionScreen.isEmpty()) { - // 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); - postedRegion = tr.transform(postedRegion); - - // 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). - postedRegion.andSelf(visibleRegionScreen); - outDirtyRegion.orSelf(postedRegion); - } - } -} - -void Layer::dump(String8& result, char* buffer, size_t SIZE) const -{ - LayerBaseClient::dump(result, buffer, SIZE); - - sp<const GraphicBuffer> buf0(mActiveBuffer); - uint32_t w0=0, h0=0, s0=0, f0=0; - if (buf0 != 0) { - w0 = buf0->getWidth(); - h0 = buf0->getHeight(); - s0 = buf0->getStride(); - f0 = buf0->format; - } - snprintf(buffer, SIZE, - " " - "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," - " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n", - mFormat, w0, h0, s0,f0, - getTransformHint(), mQueuedFrames, mRefreshPending); - - result.append(buffer); - - if (mSurfaceTexture != 0) { - mSurfaceTexture->dump(result, " ", buffer, SIZE); - } -} - -void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const -{ - LayerBaseClient::dumpStats(result, buffer, SIZE); - const size_t o = mFrameLatencyOffset; - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const nsecs_t period = hw.getRefreshPeriod(); - result.appendFormat("%lld\n", period); - for (size_t i=0 ; i<128 ; i++) { - const size_t index = (o+i) % 128; - const nsecs_t time_app = mFrameStats[index].timestamp; - const nsecs_t time_set = mFrameStats[index].set; - const nsecs_t time_vsync = mFrameStats[index].vsync; - result.appendFormat("%lld\t%lld\t%lld\n", - time_app, - time_vsync, - time_set); - } - result.append("\n"); -} - -void Layer::clearStats() -{ - LayerBaseClient::clearStats(); - memset(mFrameStats, 0, sizeof(mFrameStats)); -} - -uint32_t Layer::getEffectiveUsage(uint32_t usage) const -{ - // TODO: should we do something special if mSecure is set? - if (mProtectedByApp) { - // need a hardware-protected path to external video sink - usage |= GraphicBuffer::USAGE_PROTECTED; - } - usage |= GraphicBuffer::USAGE_HW_COMPOSER; - return usage; -} - -uint32_t Layer::getTransformHint() const { - uint32_t orientation = 0; - if (!mFlinger->mDebugDisableTransformHint) { - orientation = getPlaneOrientation(); - if (orientation & Transform::ROT_INVALID) { - orientation = 0; - } - } - return orientation; -} - -// --------------------------------------------------------------------------- - - -}; // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h deleted file mode 100644 index 8d508c2..0000000 --- a/services/surfaceflinger/Layer.h +++ /dev/null @@ -1,151 +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 <gui/SurfaceTexture.h> - -#include <utils/Timers.h> - -#include <ui/GraphicBuffer.h> -#include <ui/PixelFormat.h> - -#include <gui/ISurfaceComposerClient.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> -#include <GLES/glext.h> - -#include "LayerBase.h" -#include "SurfaceTextureLayer.h" -#include "Transform.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class Client; -class GLExtensions; - -// --------------------------------------------------------------------------- - -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); - - bool isFixedSize() const; - - // LayerBase interface - virtual void setGeometry(hwc_layer_t* hwcl); - virtual void setPerFrameData(hwc_layer_t* hwcl); - 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 bool isOpaque() const; - virtual bool needsDithering() const { return mNeedsDithering; } - virtual bool isSecure() const { return mSecure; } - virtual bool isProtected() const; - virtual void onRemoved(); - virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); } - virtual void setName(const String8& name); - - // LayerBaseClient interface - virtual wp<IBinder> getSurfaceTextureBinder() const; - - virtual void onLayerDisplayed(); - virtual bool onPreComposition(); - - // only for debugging - inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; } - -protected: - virtual void onFirstRef(); - virtual void dump(String8& result, char* scratch, size_t size) const; - virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const; - virtual void clearStats(); - -private: - friend class SurfaceTextureLayer; - void onFrameQueued(); - virtual sp<ISurface> createSurface(); - uint32_t getEffectiveUsage(uint32_t usage) const; - uint32_t getTransformHint() const; - bool isCropped() const; - static bool getOpacityForFormat(uint32_t format); - - // ----------------------------------------------------------------------- - - // constants - sp<SurfaceTextureLayer> mSurfaceTexture; - GLuint mTextureName; - - // thread-safe - volatile int32_t mQueuedFrames; - - // main thread - sp<GraphicBuffer> mActiveBuffer; - GLfloat mTextureMatrix[16]; - Rect mCurrentCrop; - uint32_t mCurrentTransform; - uint32_t mCurrentScalingMode; - bool mCurrentOpacity; - bool mRefreshPending; - bool mFrameLatencyNeeded; - int mFrameLatencyOffset; - - struct Statistics { - Statistics() : timestamp(0), set(0), vsync(0) { } - nsecs_t timestamp; // buffer timestamp - nsecs_t set; // buffer displayed timestamp - nsecs_t vsync; // vsync immediately before set - }; - - // protected by mLock - Statistics mFrameStats[128]; - - // constants - PixelFormat mFormat; - const GLExtensions& mGLExtensions; - bool mOpaqueLayer; - bool mNeedsDithering; - - // page-flip thread (currently main thread) - bool mSecure; // no screenshots - bool mProtectedByApp; // application requires protected path to external sink - Region mPostedDirtyRegion; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_H diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp deleted file mode 100644 index e764001..0000000 --- a/services/surfaceflinger/LayerBase.cpp +++ /dev/null @@ -1,582 +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" - -namespace android { - -// --------------------------------------------------------------------------- - -int32_t LayerBase::sSequence = 1; - -LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) - : dpy(display), contentDirty(false), - sequence(uint32_t(android_atomic_inc(&sSequence))), - mFlinger(flinger), mFiltering(false), - mNeedsFiltering(false), mInOverlay(false), - mOrientation(0), - mPlaneOrientation(0), - mTransactionFlags(0), - mPremultipliedAlpha(true), mName("unnamed"), mDebug(false) -{ - 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(float x, float 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; - - // we may use linear filtering, if the matrix scales us - const uint8_t type = temp.transform.getType(); - mNeedsFiltering = (!temp.transform.preserveRects() || - (type >= Transform::SCALE)); - } - - // 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(); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t hw_h = hw.getHeight(); - - 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); - for (size_t i=0 ; i<4 ; i++) - mVertices[i][1] = hw_h - mVertices[i][1]; - - if (CC_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(); - mPlaneOrientation = planeTransform.getOrientation(); - mTransform = tr; - mTransformedBounds = tr.makeBounds(w, h); -} - -void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) { -} - -void LayerBase::unlockPageFlip( - const Transform& planeTransform, Region& outDirtyRegion) { -} - -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::setGeometry(hwc_layer_t* hwcl) -{ - hwcl->compositionType = HWC_FRAMEBUFFER; - hwcl->hints = 0; - hwcl->flags = HWC_SKIP_LAYER; - hwcl->transform = 0; - hwcl->blending = HWC_BLENDING_NONE; - - // this gives us only the "orientation" component of the transform - const State& s(drawingState()); - const uint32_t finalTransform = s.transform.getOrientation(); - // we can only handle simple transformation - if (finalTransform & Transform::ROT_INVALID) { - hwcl->flags = HWC_SKIP_LAYER; - } else { - hwcl->transform = finalTransform; - } - - if (!isOpaque()) { - hwcl->blending = mPremultipliedAlpha ? - HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; - } - - // scaling is already applied in mTransformedBounds - hwcl->displayFrame.left = mTransformedBounds.left; - hwcl->displayFrame.top = mTransformedBounds.top; - hwcl->displayFrame.right = mTransformedBounds.right; - hwcl->displayFrame.bottom = mTransformedBounds.bottom; - hwcl->visibleRegionScreen.rects = - reinterpret_cast<hwc_rect_t const *>( - visibleRegionScreen.getArray( - &hwcl->visibleRegionScreen.numRects)); - - hwcl->sourceCrop.left = 0; - hwcl->sourceCrop.top = 0; - hwcl->sourceCrop.right = mTransformedBounds.width(); - hwcl->sourceCrop.bottom = mTransformedBounds.height(); -} - -void LayerBase::setPerFrameData(hwc_layer_t* hwcl) { - hwcl->compositionType = HWC_FRAMEBUFFER; - hwcl->handle = NULL; -} - -void LayerBase::setOverlay(bool inOverlay) { - mInOverlay = inOverlay; -} - -bool LayerBase::isOverlay() const { - return mInOverlay; -} - -void LayerBase::setFiltering(bool filtering) -{ - mFiltering = filtering; -} - -bool LayerBase::getFiltering() const -{ - return mFiltering; -} - -void LayerBase::draw(const Region& clip) const -{ - // reset GL state - glEnable(GL_SCISSOR_TEST); - - onDraw(clip); -} - -void LayerBase::drawForSreenShot() -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - setFiltering(true); - onDraw( Region(hw.bounds()) ); - setFiltering(false); -} - -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); - - glDisable(GL_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - 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 -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t fbHeight = hw.getHeight(); - const State& s(drawingState()); - - GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; - if (CC_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 (!isOpaque()) { - glEnable(GL_BLEND); - glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - } - - struct TexCoords { - GLfloat u; - GLfloat v; - }; - - TexCoords texCoords[4]; - texCoords[0].u = 0; - texCoords[0].v = 1; - texCoords[1].u = 0; - texCoords[1].v = 0; - texCoords[2].u = 1; - texCoords[2].v = 0; - texCoords[3].u = 1; - texCoords[3].v = 1; - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, mVertices); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - 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); - glDisable(GL_BLEND); -} - -void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const -{ - const Layer::State& s(drawingState()); - - snprintf(buffer, SIZE, - "+ %s %p (%s)\n", - getTypeId(), this, getName().string()); - result.append(buffer); - - s.transparentRegion.dump(result, "transparentRegion"); - transparentRegionScreen.dump(result, "transparentRegionScreen"); - visibleRegionScreen.dump(result, "visibleRegionScreen"); - - snprintf(buffer, SIZE, - " " - "z=%9d, pos=(%g,%g), size=(%4d,%4d), " - "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, " - "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", - s.z, s.transform.tx(), s.transform.ty(), s.w, s.h, - isOpaque(), 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); -} - -void LayerBase::shortDump(String8& result, char* scratch, size_t size) const { - LayerBase::dump(result, scratch, size); -} - -void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const { -} - -void LayerBase::clearStats() { -} - -// --------------------------------------------------------------------------- - -int32_t LayerBaseClient::sIdentity = 1; - -LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBase(flinger, display), - mHasSurface(false), - mClientRef(client), - mIdentity(uint32_t(android_atomic_inc(&sIdentity))) -{ -} - -LayerBaseClient::~LayerBaseClient() -{ - sp<Client> c(mClientRef.promote()); - if (c != 0) { - c->detachLayer(this); - } -} - -sp<ISurface> LayerBaseClient::createSurface() -{ - class BSurface : public BnSurface, public LayerCleaner { - virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; } - public: - BSurface(const sp<SurfaceFlinger>& flinger, - const sp<LayerBaseClient>& layer) - : LayerCleaner(flinger, layer) { } - }; - sp<ISurface> sur(new BSurface(mFlinger, this)); - return sur; -} - -sp<ISurface> LayerBaseClient::getSurface() -{ - sp<ISurface> s; - Mutex::Autolock _l(mLock); - - LOG_ALWAYS_FATAL_IF(mHasSurface, - "LayerBaseClient::getSurface() has already been called"); - - mHasSurface = true; - s = createSurface(); - mClientSurfaceBinder = s->asBinder(); - return s; -} - -wp<IBinder> LayerBaseClient::getSurfaceBinder() const { - return mClientSurfaceBinder; -} - -wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const { - return 0; -} - -void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const -{ - LayerBase::dump(result, buffer, SIZE); - - sp<Client> client(mClientRef.promote()); - snprintf(buffer, SIZE, - " client=%p, identity=%u\n", - client.get(), getIdentity()); - - result.append(buffer); -} - - -void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const -{ - LayerBaseClient::dump(result, scratch, size); -} - -// --------------------------------------------------------------------------- - -LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, - const sp<LayerBaseClient>& layer) - : mFlinger(flinger), mLayer(layer) { -} - -LayerBaseClient::LayerCleaner::~LayerCleaner() { - // destroy client resources - mFlinger->destroySurface(mLayer); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h deleted file mode 100644 index cd6efdd..0000000 --- a/services/surfaceflinger/LayerBase.h +++ /dev/null @@ -1,342 +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 <gui/ISurfaceComposerClient.h> - -#include <private/gui/LayerState.h> - -#include <hardware/hwcomposer.h> - -#include "DisplayHardware/DisplayHardware.h" -#include "Transform.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class Client; -class DisplayHardware; -class GraphicBuffer; -class GraphicPlane; -class Layer; -class LayerBaseClient; -class SurfaceFlinger; - -// --------------------------------------------------------------------------- - -class LayerBase : public RefBase -{ - static int32_t sSequence; - -public: - LayerBase(SurfaceFlinger* flinger, DisplayID display); - - DisplayID dpy; - mutable bool contentDirty; - Region visibleRegionScreen; - Region transparentRegionScreen; - Region coveredRegionScreen; - int32_t sequence; - - 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; - }; - - virtual void setName(const String8& name); - String8 getName() const; - - // modify current state - bool setPosition(float x, float 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; - - virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; } - virtual sp<Layer> getLayer() const { return 0; } - - virtual const char* getTypeId() const { return "LayerBase"; } - - virtual void setGeometry(hwc_layer_t* hwcl); - virtual void setPerFrameData(hwc_layer_t* hwcl); - void setOverlay(bool inOverlay); - bool isOverlay() const; - - - /** - * 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; - virtual void drawForSreenShot(); - - /** - * 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); - - /** - * isOpaque - true if this surface is opaque - */ - virtual bool isOpaque() const { return true; } - - /** - * needsDithering - true if this surface needs dithering - */ - virtual bool needsDithering() const { return false; } - - /** - * needsLinearFiltering - true if this surface's state requires 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; } - - /** - * isProtected - true if the layer may contain protected content in the - * GRALLOC_USAGE_PROTECTED sense. - */ - virtual bool isProtected() const { return false; } - - /** called with the state lock when the surface is removed from the - * current list */ - virtual void onRemoved() { } - - /** called after page-flip - */ - virtual void onLayerDisplayed() { } - - /** called before composition. - * returns true if the layer has pending updates. - */ - virtual bool onPreComposition() { return false; } - - /** always call base class first */ - virtual void dump(String8& result, char* scratch, size_t size) const; - virtual void shortDump(String8& result, char* scratch, size_t size) const; - virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const; - virtual void clearStats(); - - - 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; } - - int32_t getOrientation() const { return mOrientation; } - int32_t getPlaneOrientation() const { return mPlaneOrientation; } - -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; - - void setFiltering(bool filtering); - bool getFiltering() const; - - sp<SurfaceFlinger> mFlinger; - uint32_t mFlags; - -private: - // accessed only in the main thread - // Whether filtering is forced on or not - bool mFiltering; - - // cached during validateVisibility() - // Whether filtering is needed b/c of the drawingstate - bool mNeedsFiltering; - - // this layer is currently handled by the hwc. this is - // updated at composition time, always frmo the composition - // thread. - bool mInOverlay; - -protected: - // cached during validateVisibility() - int32_t mOrientation; - int32_t mPlaneOrientation; - Transform mTransform; - GLfloat mVertices[4][2]; - Rect mTransformedBounds; - - // 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; - - -public: - // called from class SurfaceFlinger - virtual ~LayerBase(); - -private: - LayerBase(const LayerBase& rhs); -}; - - -// --------------------------------------------------------------------------- - -class LayerBaseClient : public LayerBase -{ -public: - LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - - virtual ~LayerBaseClient(); - - sp<ISurface> getSurface(); - wp<IBinder> getSurfaceBinder() const; - virtual wp<IBinder> getSurfaceTextureBinder() const; - - virtual sp<LayerBaseClient> getLayerBaseClient() const { - return const_cast<LayerBaseClient*>(this); } - - virtual const char* getTypeId() const { return "LayerBaseClient"; } - - uint32_t getIdentity() const { return mIdentity; } - -protected: - virtual void dump(String8& result, char* scratch, size_t size) const; - virtual void shortDump(String8& result, char* scratch, size_t size) const; - - class LayerCleaner { - sp<SurfaceFlinger> mFlinger; - wp<LayerBaseClient> mLayer; - protected: - ~LayerCleaner(); - public: - LayerCleaner(const sp<SurfaceFlinger>& flinger, - const sp<LayerBaseClient>& layer); - }; - -private: - virtual sp<ISurface> createSurface(); - - mutable Mutex mLock; - mutable bool mHasSurface; - wp<IBinder> mClientSurfaceBinder; - const wp<Client> mClientRef; - // only read - const uint32_t mIdentity; - static int32_t sIdentity; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_BASE_H diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp deleted file mode 100644 index e665d7a..0000000 --- a/services/surfaceflinger/LayerDim.cpp +++ /dev/null @@ -1,79 +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 { -// --------------------------------------------------------------------------- - -LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBaseClient(flinger, display, client) -{ -} - -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_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); - - if (s.alpha == 0xFF) { - glDisable(GL_BLEND); - } else { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - glColor4f(0, 0, 0, alpha); - - 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); - } - glDisable(GL_BLEND); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h deleted file mode 100644 index 8770e6d..0000000 --- a/services/surfaceflinger/LayerDim.h +++ /dev/null @@ -1,51 +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 -{ -public: - LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - virtual ~LayerDim(); - - virtual void onDraw(const Region& clip) const; - virtual bool isOpaque() const { return false; } - virtual bool isSecure() const { return false; } - virtual bool isProtectedByApp() const { return false; } - virtual bool isProtectedByDRM() const { return false; } - virtual const char* getTypeId() const { return "LayerDim"; } -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_DIM_H diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp deleted file mode 100644 index c7cf46e..0000000 --- a/services/surfaceflinger/LayerScreenshot.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2011 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 "LayerScreenshot.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" - - -namespace android { -// --------------------------------------------------------------------------- - -LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client) - : LayerBaseClient(flinger, display, client), - mTextureName(0), mFlinger(flinger) -{ -} - -LayerScreenshot::~LayerScreenshot() -{ - if (mTextureName) { - mFlinger->postMessageAsync( - new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); - } -} - -status_t LayerScreenshot::captureLocked() { - GLfloat u, v; - status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v); - if (result != NO_ERROR) { - return result; - } - initTexture(u, v); - return NO_ERROR; -} - -status_t LayerScreenshot::capture() { - GLfloat u, v; - status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v); - if (result != NO_ERROR) { - return result; - } - initTexture(u, v); - return NO_ERROR; -} - -void LayerScreenshot::initTexture(GLfloat u, GLfloat v) { - glBindTexture(GL_TEXTURE_2D, mTextureName); - 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_CLAMP_TO_EDGE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - mTexCoords[0] = 0; mTexCoords[1] = v; - mTexCoords[2] = 0; mTexCoords[3] = 0; - mTexCoords[4] = u; mTexCoords[5] = 0; - mTexCoords[6] = u; mTexCoords[7] = v; -} - -void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) { - LayerBaseClient::initStates(w, h, flags); - if (!(flags & ISurfaceComposer::eHidden)) { - capture(); - } -} - -uint32_t LayerScreenshot::doTransaction(uint32_t flags) -{ - const Layer::State& draw(drawingState()); - const Layer::State& curr(currentState()); - - if (draw.flags & ISurfaceComposer::eLayerHidden) { - if (!(curr.flags & ISurfaceComposer::eLayerHidden)) { - // we're going from hidden to visible - status_t err = captureLocked(); - if (err != NO_ERROR) { - ALOGW("createScreenshotSurface failed (%s)", strerror(-err)); - } - } - } else if (curr.flags & ISurfaceComposer::eLayerHidden) { - // we're going from visible to hidden - if (mTextureName) { - glDeleteTextures(1, &mTextureName); - mTextureName = 0; - } - } - return LayerBaseClient::doTransaction(flags); -} - -void LayerScreenshot::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(); - - if (s.alpha == 0xFF) { - glDisable(GL_BLEND); - } else { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - glColor4f(0, 0, 0, alpha); - - glDisable(GL_TEXTURE_EXTERNAL_OES); - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, mTextureName); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords); - 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); - } - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h deleted file mode 100644 index ab90047..0000000 --- a/services/surfaceflinger/LayerScreenshot.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 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_SCREENSHOT_H -#define ANDROID_LAYER_SCREENSHOT_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include "LayerBase.h" - -// --------------------------------------------------------------------------- - -namespace android { - -class LayerScreenshot : public LayerBaseClient -{ - GLuint mTextureName; - GLfloat mTexCoords[8]; - sp<SurfaceFlinger> mFlinger; -public: - LayerScreenshot(SurfaceFlinger* flinger, DisplayID display, - const sp<Client>& client); - virtual ~LayerScreenshot(); - - status_t capture(); - - virtual void initStates(uint32_t w, uint32_t h, uint32_t flags); - virtual uint32_t doTransaction(uint32_t flags); - virtual void onDraw(const Region& clip) const; - virtual bool isOpaque() const { return false; } - virtual bool isSecure() const { return false; } - virtual bool isProtectedByApp() const { return false; } - virtual bool isProtectedByDRM() const { return false; } - virtual const char* getTypeId() const { return "LayerScreenshot"; } - -private: - status_t captureLocked(); - void initTexture(GLfloat u, GLfloat v); -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_SCREENSHOT_H diff --git a/services/surfaceflinger/MODULE_LICENSE_APACHE2 b/services/surfaceflinger/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/services/surfaceflinger/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp deleted file mode 100644 index 290fff4..0000000 --- a/services/surfaceflinger/MessageQueue.cpp +++ /dev/null @@ -1,165 +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 <binder/IPCThreadState.h> - -#include <utils/threads.h> -#include <utils/Timers.h> -#include <utils/Log.h> - -#include <gui/IDisplayEventConnection.h> -#include <gui/BitTube.h> - -#include "MessageQueue.h" -#include "EventThread.h" -#include "SurfaceFlinger.h" - -namespace android { - -// --------------------------------------------------------------------------- - -MessageBase::MessageBase() - : MessageHandler() { -} - -MessageBase::~MessageBase() { -} - -void MessageBase::handleMessage(const Message&) { - this->handler(); - barrier.open(); -}; - -// --------------------------------------------------------------------------- - -void MessageQueue::Handler::signalRefresh() { - if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) { - mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH)); - } -} - -void MessageQueue::Handler::signalInvalidate() { - if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) { - mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE)); - } -} - -void MessageQueue::Handler::handleMessage(const Message& message) { - switch (message.what) { - case INVALIDATE: - android_atomic_and(~eventMaskInvalidate, &mEventMask); - mQueue.mFlinger->onMessageReceived(message.what); - break; - case REFRESH: - android_atomic_and(~eventMaskRefresh, &mEventMask); - mQueue.mFlinger->onMessageReceived(message.what); - break; - } -} - -// --------------------------------------------------------------------------- - -MessageQueue::MessageQueue() -{ -} - -MessageQueue::~MessageQueue() { -} - -void MessageQueue::init(const sp<SurfaceFlinger>& flinger) -{ - mFlinger = flinger; - mLooper = new Looper(true); - mHandler = new Handler(*this); -} - -void MessageQueue::setEventThread(const sp<EventThread>& eventThread) -{ - mEventThread = eventThread; - mEvents = eventThread->createEventConnection(); - mEventTube = mEvents->getDataChannel(); - mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT, - MessageQueue::cb_eventReceiver, this); -} - -void MessageQueue::waitMessage() { - do { - IPCThreadState::self()->flushCommands(); - int32_t ret = mLooper->pollOnce(-1); - switch (ret) { - case ALOOPER_POLL_WAKE: - case ALOOPER_POLL_CALLBACK: - continue; - case ALOOPER_POLL_ERROR: - ALOGE("ALOOPER_POLL_ERROR"); - case ALOOPER_POLL_TIMEOUT: - // timeout (should not happen) - continue; - default: - // should not happen - ALOGE("Looper::pollOnce() returned unknown status %d", ret); - continue; - } - } while (true); -} - -status_t MessageQueue::postMessage( - const sp<MessageBase>& messageHandler, nsecs_t relTime) -{ - const Message dummyMessage; - if (relTime > 0) { - mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage); - } else { - mLooper->sendMessage(messageHandler, dummyMessage); - } - return NO_ERROR; -} - -void MessageQueue::invalidate() { -// mHandler->signalInvalidate(); - mEvents->requestNextVsync(); -} - -void MessageQueue::refresh() { - mEvents->requestNextVsync(); -} - -int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { - MessageQueue* queue = reinterpret_cast<MessageQueue *>(data); - return queue->eventReceiver(fd, events); -} - -int MessageQueue::eventReceiver(int fd, int events) { - ssize_t n; - DisplayEventReceiver::Event buffer[8]; - while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) { - for (int i=0 ; i<n ; i++) { - if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { - mHandler->signalRefresh(); - break; - } - } - } - return 1; -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h deleted file mode 100644 index ea29e7e..0000000 --- a/services/surfaceflinger/MessageQueue.h +++ /dev/null @@ -1,111 +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/Looper.h> - -#include <gui/DisplayEventReceiver.h> - -#include "Barrier.h" - -namespace android { - -class IDisplayEventConnection; -class EventThread; -class SurfaceFlinger; - -// --------------------------------------------------------------------------- - -class MessageBase : public MessageHandler -{ -public: - MessageBase(); - - // return true if message has a handler - virtual bool handler() = 0; - - // waits for the handler to be processed - void wait() const { barrier.wait(); } - -protected: - virtual ~MessageBase(); - -private: - virtual void handleMessage(const Message& message); - - mutable Barrier barrier; -}; - -// --------------------------------------------------------------------------- - -class MessageQueue { - class Handler : public MessageHandler { - enum { - eventMaskInvalidate = 0x1, - eventMaskRefresh = 0x2 - }; - MessageQueue& mQueue; - int32_t mEventMask; - public: - Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { } - virtual void handleMessage(const Message& message); - void signalRefresh(); - void signalInvalidate(); - }; - - friend class Handler; - - sp<SurfaceFlinger> mFlinger; - sp<Looper> mLooper; - sp<EventThread> mEventThread; - sp<IDisplayEventConnection> mEvents; - sp<BitTube> mEventTube; - sp<Handler> mHandler; - - - static int cb_eventReceiver(int fd, int events, void* data); - int eventReceiver(int fd, int events); - -public: - enum { - INVALIDATE = 0, - REFRESH = 1, - }; - - MessageQueue(); - ~MessageQueue(); - void init(const sp<SurfaceFlinger>& flinger); - void setEventThread(const sp<EventThread>& events); - - void waitMessage(); - status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0); - void invalidate(); - void refresh(); -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif /* ANDROID_MESSAGE_QUEUE_H */ diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp deleted file mode 100644 index 7f61fe4..0000000 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ /dev/null @@ -1,2812 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS - -#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 <binder/PermissionCache.h> - -#include <gui/IDisplayEventConnection.h> - -#include <utils/String8.h> -#include <utils/String16.h> -#include <utils/StopWatch.h> -#include <utils/Trace.h> - -#include <ui/GraphicBufferAllocator.h> -#include <ui/PixelFormat.h> - -#include <GLES/gl.h> - -#include "clz.h" -#include "DdmConnection.h" -#include "DisplayEventConnection.h" -#include "EventThread.h" -#include "GLExtensions.h" -#include "Layer.h" -#include "LayerDim.h" -#include "LayerScreenshot.h" -#include "SurfaceFlinger.h" - -#include "DisplayHardware/DisplayHardware.h" -#include "DisplayHardware/HWComposer.h" - -#include <private/android_filesystem_config.h> -#include <private/gui/SharedBufferStack.h> - -#define EGL_VERSION_HW_ANDROID 0x3143 - -#define DISPLAY_COUNT 1 - -namespace android { -// --------------------------------------------------------------------------- - -const String16 sHardwareTest("android.permission.HARDWARE_TEST"); -const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); -const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); -const String16 sDump("android.permission.DUMP"); - -// --------------------------------------------------------------------------- - -SurfaceFlinger::SurfaceFlinger() - : BnSurfaceComposer(), Thread(false), - mTransactionFlags(0), - mTransationPending(false), - mLayersRemoved(false), - mBootTime(systemTime()), - mVisibleRegionsDirty(false), - mHwWorkListDirty(false), - mElectronBeamAnimationMode(0), - mDebugRegion(0), - mDebugBackground(0), - mDebugDDMS(0), - mDebugDisableHWC(0), - mDebugDisableTransformHint(0), - mDebugInSwapBuffers(0), - mLastSwapBufferTime(0), - mDebugInTransaction(0), - mLastTransactionTime(0), - mBootFinished(false), - mConsoleSignals(0), - mSecureFrameBuffer(0) -{ - init(); -} - -void SurfaceFlinger::init() -{ - ALOGI("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); - - property_get("debug.sf.ddms", value, "0"); - mDebugDDMS = atoi(value); - if (mDebugDDMS) { - DdmConnection::start(getServiceName()); - } - - ALOGI_IF(mDebugRegion, "showupdates enabled"); - ALOGI_IF(mDebugBackground, "showbackground enabled"); - ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); -} - -void SurfaceFlinger::onFirstRef() -{ - mEventQueue.init(this); - - run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); - - // Wait for the main thread to be done with its initialization - mReadyToRunBarrier.wait(); -} - - -SurfaceFlinger::~SurfaceFlinger() -{ - glDeleteTextures(1, &mWormholeTexName); -} - -void SurfaceFlinger::binderDied(const wp<IBinder>& who) -{ - // the window manager died on us. prepare its eulogy. - - // reset screen orientation - Vector<ComposerState> state; - setTransactionState(state, eOrientationDefault, 0); - - // restart the boot-animation - property_set("ctl.start", "bootanim"); -} - -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<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() -{ - sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); - return gba; -} - -const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const -{ - ALOGE_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; - ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); - mBootFinished = true; - - // wait patiently for the window manager death - const String16 name("window"); - sp<IBinder> window(defaultServiceManager()->getService(name)); - if (window != 0) { - window->linkToDeath(this); - } - - // stop boot animation - property_set("ctl.stop", "bootanim"); -} - -static inline uint16_t pack565(int r, int g, int b) { - return (r<<11)|(g<<5)|b; -} - -status_t SurfaceFlinger::readyToRun() -{ - ALOGI( "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"); - ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); - - mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); - ALOGE_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 wormholeTexData[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, wormholeTexData); - - const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; - glGenTextures(1, &mProtectedTexName); - glBindTexture(GL_TEXTURE_2D, mProtectedTexName); - 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, 1, 1, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); - - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - // put the origin in the left-bottom corner - glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h - - - // start the EventThread - mEventThread = new EventThread(this); - mEventQueue.setEventThread(mEventThread); - hw.startSleepManagement(); - - /* - * We're now ready to accept clients... - */ - - mReadyToRunBarrier.open(); - - // start boot animation - property_set("ctl.start", "bootanim"); - - return NO_ERROR; -} - -// ---------------------------------------------------------------------------- - -bool SurfaceFlinger::authenticateSurfaceTexture( - const sp<ISurfaceTexture>& surfaceTexture) const { - Mutex::Autolock _l(mStateLock); - sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); - - // Check the visible layer list for the ISurface - const LayerVector& currentLayers = mCurrentState.layersSortedByZ; - size_t count = currentLayers.size(); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); - sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); - if (lbc != NULL) { - wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } - } - } - - // Check the layers in the purgatory. This check is here so that if a - // SurfaceTexture gets destroyed before all the clients are done using it, - // the error will not be reported as "surface XYZ is not authenticated", but - // will instead fail later on when the client tries to use the surface, - // which should be reported as "surface XYZ returned an -ENODEV". The - // purgatorized layers are no less authentic than the visible ones, so this - // should not cause any harm. - size_t purgatorySize = mLayerPurgatory.size(); - for (size_t i=0 ; i<purgatorySize ; i++) { - const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); - sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); - if (lbc != NULL) { - wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } - } - } - - return false; -} - -// ---------------------------------------------------------------------------- - -sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { - return mEventThread->createEventConnection(); -} - -// ---------------------------------------------------------------------------- - -void SurfaceFlinger::waitForEvent() { - mEventQueue.waitMessage(); -} - -void SurfaceFlinger::signalTransaction() { - mEventQueue.invalidate(); -} - -void SurfaceFlinger::signalLayerUpdate() { - mEventQueue.invalidate(); -} - -void SurfaceFlinger::signalRefresh() { - mEventQueue.refresh(); -} - -status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, - nsecs_t reltime, uint32_t flags) { - return mEventQueue.postMessage(msg, reltime); -} - -status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, - nsecs_t reltime, uint32_t flags) { - status_t res = mEventQueue.postMessage(msg, reltime); - if (res == NO_ERROR) { - msg->wait(); - } - return res; -} - -bool SurfaceFlinger::threadLoop() -{ - waitForEvent(); - return true; -} - -void SurfaceFlinger::onMessageReceived(int32_t what) -{ - ATRACE_CALL(); - switch (what) { - case MessageQueue::REFRESH: { -// case MessageQueue::INVALIDATE: { - // check for transactions - if (CC_UNLIKELY(mConsoleSignals)) { - handleConsoleEvents(); - } - - // if we're in a global transaction, don't do anything. - const uint32_t mask = eTransactionNeeded | eTraversalNeeded; - uint32_t transactionFlags = peekTransactionFlags(mask); - if (CC_UNLIKELY(transactionFlags)) { - handleTransaction(transactionFlags); - } - - // post surfaces (if needed) - handlePageFlip(); - -// signalRefresh(); -// -// } break; -// -// case MessageQueue::REFRESH: { - - handleRefresh(); - - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - -// if (mDirtyRegion.isEmpty()) { -// return; -// } - - if (CC_UNLIKELY(mHwWorkListDirty)) { - // build the h/w work list - handleWorkList(); - } - - if (CC_LIKELY(hw.canDraw())) { - // repaint the framebuffer (if needed) - handleRepaint(); - // inform the h/w that we're done compositing - hw.compositionComplete(); - postFramebuffer(); - } else { - // pretend we did the post - hw.compositionComplete(); - } - - } break; - } -} - -void SurfaceFlinger::postFramebuffer() -{ - ATRACE_CALL(); - // mSwapRegion can be empty here is some cases, for instance if a hidden - // or fully transparent window is updating. - // in that case, we need to flip anyways to not risk a deadlock with - // h/w composer. - - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const nsecs_t now = systemTime(); - mDebugInSwapBuffers = now; - hw.flip(mSwapRegion); - - size_t numLayers = mVisibleLayersSortedByZ.size(); - for (size_t i = 0; i < numLayers; i++) { - mVisibleLayersSortedByZ[i]->onLayerDisplayed(); - } - - mLastSwapBufferTime = systemTime() - now; - mDebugInSwapBuffers = 0; - mSwapRegion.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(); - // this is a temporary work-around, eventually this should be called - // by the power-manager - SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); - } - - if (what & eConsoleReleased) { - if (hw.isScreenAcquired()) { - hw.releaseScreen(); - } - } - - mDirtyRegion.set(hw.bounds()); -} - -void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) -{ - ATRACE_CALL(); - - Mutex::Autolock _l(mStateLock); - const nsecs_t now = systemTime(); - mDebugInTransaction = now; - - // Here we're guaranteed that some transaction flags are set - // so we can call handleTransactionLocked() unconditionally. - // We call getTransactionFlags(), which will also clear the flags, - // with mStateLock held to guarantee that mCurrentState won't change - // until the transaction is committed. - - const uint32_t mask = eTransactionNeeded | eTraversalNeeded; - transactionFlags = getTransactionFlags(mask); - handleTransactionLocked(transactionFlags); - - mLastTransactionTime = systemTime() - now; - mDebugInTransaction = 0; - invalidateHwcGeometry(); - // here the transaction has been committed -} - -void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) -{ - 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; - // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; - 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 (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 - mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); - } - } - } - } - - commitTransaction(); -} - -void SurfaceFlinger::computeVisibleRegions( - const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) -{ - ATRACE_CALL(); - - 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 (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { - const bool translucent = !layer->isOpaque(); - 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() -{ - if (!mLayersPendingRemoval.isEmpty()) { - // Notify removed layers now that they can't be drawn from - for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { - mLayersPendingRemoval[i]->onRemoved(); - } - mLayersPendingRemoval.clear(); - } - - mDrawingState = mCurrentState; - mTransationPending = false; - mTransactionCV.broadcast(); -} - -void SurfaceFlinger::handlePageFlip() -{ - ATRACE_CALL(); - const DisplayHardware& hw = graphicPlane(0).displayHardware(); - const Region screenRegion(hw.bounds()); - - const LayerVector& currentLayers(mDrawingState.layersSortedByZ); - const bool visibleRegions = lockPageFlip(currentLayers); - - if (visibleRegions || mVisibleRegionsDirty) { - Region opaqueRegion; - computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); - - /* - * rebuild the visible layer list - */ - const size_t count = currentLayers.size(); - mVisibleLayersSortedByZ.clear(); - mVisibleLayersSortedByZ.setCapacity(count); - for (size_t i=0 ; i<count ; i++) { - if (!currentLayers[i]->visibleRegionScreen.isEmpty()) - mVisibleLayersSortedByZ.add(currentLayers[i]); - } - - mWormholeRegion = screenRegion.subtract(opaqueRegion); - mVisibleRegionsDirty = false; - invalidateHwcGeometry(); - } - - unlockPageFlip(currentLayers); - - mDirtyRegion.orSelf(getAndClearInvalidateRegion()); - mDirtyRegion.andSelf(screenRegion); -} - -void SurfaceFlinger::invalidateHwcGeometry() -{ - mHwWorkListDirty = true; -} - -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()); - const 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::handleRefresh() -{ - bool needInvalidate = false; - const LayerVector& currentLayers(mDrawingState.layersSortedByZ); - const size_t count = currentLayers.size(); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); - if (layer->onPreComposition()) { - needInvalidate = true; - } - } - if (needInvalidate) { - signalLayerUpdate(); - } -} - - -void SurfaceFlinger::handleWorkList() -{ - mHwWorkListDirty = false; - HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); - if (hwc.initCheck() == NO_ERROR) { - const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); - const size_t count = currentLayers.size(); - hwc.createWorkList(count); - hwc_layer_t* const cur(hwc.getLayers()); - for (size_t i=0 ; cur && i<count ; i++) { - currentLayers[i]->setGeometry(&cur[i]); - if (mDebugDisableHWC || mDebugRegion) { - cur[i].compositionType = HWC_FRAMEBUFFER; - cur[i].flags |= HWC_SKIP_LAYER; - } - } - } -} - -void SurfaceFlinger::handleRepaint() -{ - ATRACE_CALL(); - - // compute the invalid region - mSwapRegion.orSelf(mDirtyRegion); - - if (CC_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(mSwapRegion.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(mSwapRegion.bounds()); - } else { - // we need to redraw everything (the whole screen) - mDirtyRegion.set(hw.bounds()); - mSwapRegion = mDirtyRegion; - } - } - - setupHardwareComposer(mDirtyRegion); - composeSurfaces(mDirtyRegion); - - // update the swap region and clear the dirty region - mSwapRegion.orSelf(mDirtyRegion); - mDirtyRegion.clear(); -} - -void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut) -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - HWComposer& hwc(hw.getHwComposer()); - hwc_layer_t* const cur(hwc.getLayers()); - if (!cur) { - return; - } - - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); - size_t count = layers.size(); - - ALOGE_IF(hwc.getNumLayers() != count, - "HAL number of layers (%d) doesn't match surfaceflinger (%d)", - hwc.getNumLayers(), count); - - // just to be extra-safe, use the smallest count - if (hwc.initCheck() == NO_ERROR) { - count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); - } - - /* - * update the per-frame h/w composer data for each layer - * and build the transparent region of the FB - */ - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(layers[i]); - layer->setPerFrameData(&cur[i]); - } - const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); - status_t err = hwc.prepare(); - ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); - - if (err == NO_ERROR) { - // what's happening here is tricky. - // we want to clear all the layers with the CLEAR_FB flags - // that are opaque. - // however, since some GPU are efficient at preserving - // the backbuffer, we want to take advantage of that so we do the - // clear only in the dirty region (other areas will be preserved - // on those GPUs). - // NOTE: on non backbuffer preserving GPU, the dirty region - // has already been expanded as needed, so the code is correct - // there too. - // - // However, the content of the framebuffer cannot be trusted when - // we switch to/from FB/OVERLAY, in which case we need to - // expand the dirty region to those areas too. - // - // Note also that there is a special case when switching from - // "no layers in FB" to "some layers in FB", where we need to redraw - // the entire FB, since some areas might contain uninitialized - // data. - // - // Also we want to make sure to not clear areas that belong to - // layers above that won't redraw (we would just be erasing them), - // that is, we can't erase anything outside the dirty region. - - Region transparent; - - if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) { - transparent.set(hw.getBounds()); - dirtyInOut = transparent; - } else { - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(layers[i]); - if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { - transparent.orSelf(layer->visibleRegionScreen); - } - bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER); - if (isOverlay != layer->isOverlay()) { - // we transitioned to/from overlay, so add this layer - // to the dirty region so the framebuffer can be either - // cleared or redrawn. - dirtyInOut.orSelf(layer->visibleRegionScreen); - } - layer->setOverlay(isOverlay); - } - // don't erase stuff outside the dirty region - transparent.andSelf(dirtyInOut); - } - - /* - * clear the area of the FB that need to be transparent - */ - if (!transparent.isEmpty()) { - glClearColor(0,0,0,0); - Region::const_iterator it = transparent.begin(); - Region::const_iterator const end = transparent.end(); - const int32_t height = hw.getHeight(); - 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); - } - } - } -} - -void SurfaceFlinger::composeSurfaces(const Region& dirty) -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - HWComposer& hwc(hw.getHwComposer()); - - const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); - if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) { - // should never happen unless the window manager has a bug - // draw something... - drawWormhole(); - } - - // FIXME: workaroud for b/6020860 - glEnable(GL_SCISSOR_TEST); - glScissor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT); - // end-workaround - - /* - * and then, render the layers targeted at the framebuffer - */ - hwc_layer_t* const cur(hwc.getLayers()); - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); - size_t count = layers.size(); - for (size_t i=0 ; i<count ; i++) { - if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) { - continue; - } - const sp<LayerBase>& layer(layers[i]); - const Region clip(dirty.intersect(layer->visibleRegionScreen)); - if (!clip.isEmpty()) { - layer->draw(clip); - } - } -} - -void SurfaceFlinger::debugFlashRegions() -{ - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t flags = hw.getFlags(); - const int32_t height = hw.getHeight(); - if (mSwapRegion.isEmpty()) { - return; - } - - if (!((flags & DisplayHardware::SWAP_RECTANGLE) || - (flags & DisplayHardware::BUFFER_PRESERVED))) { - const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? - mDirtyRegion.bounds() : hw.bounds()); - composeSurfaces(repaint); - } - - glDisable(GL_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - 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, height - r.top }, - { r.left, height - r.bottom }, - { r.right, height - r.bottom }, - { r.right, height - r.top } - }; - glVertexPointer(2, GL_FLOAT, 0, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - hw.flip(mSwapRegion); - - if (mDebugRegion > 1) - usleep(mDebugRegion * 1000); - - glEnable(GL_SCISSOR_TEST); -} - -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(); - - if (CC_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); - - glDisable(GL_TEXTURE_EXTERNAL_OES); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, mWormholeTexName); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - glDisable(GL_BLEND); - - 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); - glDisable(GL_TEXTURE_2D); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - } -} - -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); - return (i < 0) ? status_t(i) : status_t(NO_ERROR); -} - -ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, - const sp<LayerBaseClient>& lbc) -{ - // attach this layer to the client - size_t name = client->attachLayer(lbc); - - Mutex::Autolock _l(mStateLock); - - // add this layer to the current state list - addLayer_l(lbc); - - return ssize_t(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->getSurfaceBinder() ); - } - 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) -{ - // First add the layer to the purgatory list, which makes sure it won't - // go away, then remove it from the main list (through a transaction). - ssize_t err = removeLayer_l(layerBase); - if (err >= 0) { - mLayerPurgatory.add(layerBase); - } - - mLayersPendingRemoval.push(layerBase); - - // 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::peekTransactionFlags(uint32_t flags) -{ - return android_atomic_release_load(&mTransactionFlags); -} - -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 - signalTransaction(); - } - return old; -} - - -void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, - int orientation, uint32_t flags) { - Mutex::Autolock _l(mStateLock); - - uint32_t transactionFlags = 0; - if (mCurrentState.orientation != orientation) { - if (uint32_t(orientation)<=eOrientation270 || orientation==42) { - mCurrentState.orientation = orientation; - transactionFlags |= eTransactionNeeded; - } else if (orientation != eOrientationUnchanged) { - ALOGW("setTransactionState: ignoring unrecognized orientation: %d", - orientation); - } - } - - const size_t count = state.size(); - for (size_t i=0 ; i<count ; i++) { - const ComposerState& s(state[i]); - sp<Client> client( static_cast<Client *>(s.client.get()) ); - transactionFlags |= setClientStateLocked(client, s.state); - } - - if (transactionFlags) { - // this triggers the transaction - setTransactionFlags(transactionFlags); - - // if this is a synchronous transaction, wait for it to take effect - // before returning. - if (flags & eSynchronous) { - mTransationPending = true; - } - while (mTransationPending) { - 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. - ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); - mTransationPending = false; - break; - } - } - } -} - -sp<ISurface> SurfaceFlinger::createSurface( - ISurfaceComposerClient::surface_data_t* params, - const String8& name, - const sp<Client>& client, - DisplayID d, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) -{ - sp<LayerBaseClient> layer; - sp<ISurface> surfaceHandle; - - if (int32_t(w|h) < 0) { - ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", - int(w), int(h)); - return surfaceHandle; - } - - //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); - sp<Layer> normalLayer; - switch (flags & eFXSurfaceMask) { - case eFXSurfaceNormal: - normalLayer = createNormalSurface(client, d, w, h, flags, format); - layer = normalLayer; - break; - case eFXSurfaceBlur: - // for now we treat Blur as Dim, until we can implement it - // efficiently. - case eFXSurfaceDim: - layer = createDimSurface(client, d, w, h, flags); - break; - case eFXSurfaceScreenshot: - layer = createScreenshotSurface(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 = layer->getIdentity(); - if (normalLayer != 0) { - Mutex::Autolock _l(mStateLock); - mLayerMap.add(layer->getSurfaceBinder(), 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 (CC_LIKELY(err != NO_ERROR)) { - ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); - layer.clear(); - } - 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); - return layer; -} - -sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags) -{ - sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client); - 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 wp<LayerBaseClient>& layer) -{ - // called by ~ISurface() when all references are gone - status_t err = NO_ERROR; - sp<LayerBaseClient> l(layer.promote()); - if (l != NULL) { - Mutex::Autolock _l(mStateLock); - err = removeLayer_l(l); - if (err == NAME_NOT_FOUND) { - // The surface wasn't in the current list, which means it was - // removed already, which means it is in the purgatory, - // and need to be removed from there. - ssize_t idx = mLayerPurgatory.remove(l); - ALOGE_IF(idx < 0, - "layer=%p is not in the purgatory list", l.get()); - } - ALOGE_IF(err<0 && err != NAME_NOT_FOUND, - "error removing layer=%p (%s)", l.get(), strerror(-err)); - } - return err; -} - -uint32_t SurfaceFlinger::setClientStateLocked( - const sp<Client>& client, - const layer_state_t& s) -{ - uint32_t flags = 0; - 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) { - ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); - if (layer->setLayer(s.z)) { - mCurrentState.layersSortedByZ.removeAt(idx); - mCurrentState.layersSortedByZ.add(layer); - // we need traversal (state changed) - // AND transaction (list changed) - flags |= eTransactionNeeded|eTraversalNeeded; - } - } - if (what & eSizeChanged) { - if (layer->setSize(s.w, s.h)) { - flags |= eTraversalNeeded; - } - } - 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; - } - } - return flags; -} - -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); - signalTransaction(); -} - -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); - signalTransaction(); -} - -status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) -{ - const size_t SIZE = 4096; - char buffer[SIZE]; - String8 result; - - if (!PermissionCache::checkCallingPermission(sDump)) { - 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 { - // 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); - } - - bool dumpAll = true; - size_t index = 0; - size_t numArgs = args.size(); - if (numArgs) { - dumpAll = false; - - if ((index < numArgs) && - (args[index] == String16("--list"))) { - index++; - listLayersLocked(args, index, result, buffer, SIZE); - } - - if ((index < numArgs) && - (args[index] == String16("--latency"))) { - index++; - dumpStatsLocked(args, index, result, buffer, SIZE); - } - - if ((index < numArgs) && - (args[index] == String16("--latency-clear"))) { - index++; - clearStatsLocked(args, index, result, buffer, SIZE); - } - } - - if (dumpAll) { - dumpAllLocked(result, buffer, SIZE); - } - - if (locked) { - mStateLock.unlock(); - } - } - write(fd, result.string(), result.size()); - return NO_ERROR; -} - -void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const -{ - 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]); - snprintf(buffer, SIZE, "%s\n", layer->getName().string()); - result.append(buffer); - } -} - -void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const -{ - String8 name; - if (index < args.size()) { - name = String8(args[index]); - index++; - } - - 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]); - if (name.isEmpty()) { - snprintf(buffer, SIZE, "%s\n", layer->getName().string()); - result.append(buffer); - } - if (name.isEmpty() || (name == layer->getName())) { - layer->dumpStats(result, buffer, SIZE); - } - } -} - -void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const -{ - String8 name; - if (index < args.size()) { - name = String8(args[index]); - index++; - } - - 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]); - if (name.isEmpty() || (name == layer->getName())) { - layer->clearStats(); - } - } -} - -void SurfaceFlinger::dumpAllLocked( - String8& result, char* buffer, size_t SIZE) const -{ - // 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; - - /* - * Dump the visible layer list - */ - const LayerVector& currentLayers = mCurrentState.layersSortedByZ; - const size_t count = currentLayers.size(); - snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); - result.append(buffer); - for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); - layer->dump(result, buffer, SIZE); - } - - /* - * Dump the layers in the purgatory - */ - - const size_t purgatorySize = mLayerPurgatory.size(); - snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); - result.append(buffer); - for (size_t i=0 ; i<purgatorySize ; i++) { - const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); - layer->shortDump(result, buffer, SIZE); - } - - /* - * Dump SurfaceFlinger global state - */ - - snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); - result.append(buffer); - - const GLExtensions& extensions(GLExtensions::getInstance()); - snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", - extensions.getVendor(), - extensions.getRenderer(), - extensions.getVersion()); - result.append(buffer); - - snprintf(buffer, SIZE, "EGL : %s\n", - eglQueryString(graphicPlane(0).getEGLDisplay(), - EGL_VERSION_HW_ANDROID)); - result.append(buffer); - - snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); - result.append(buffer); - - mWormholeRegion.dump(result, "WormholeRegion"); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - snprintf(buffer, SIZE, - " orientation=%d, canDraw=%d\n", - mCurrentState.orientation, hw.canDraw()); - result.append(buffer); - snprintf(buffer, SIZE, - " last eglSwapBuffers() time: %f us\n" - " last transaction time : %f us\n" - " transaction-flags : %08x\n" - " refresh-rate : %f fps\n" - " x-dpi : %f\n" - " y-dpi : %f\n", - mLastSwapBufferTime/1000.0, - mLastTransactionTime/1000.0, - mTransactionFlags, - hw.getRefreshRate(), - hw.getDpiX(), - hw.getDpiY()); - result.append(buffer); - - snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", - inSwapBuffersDuration/1000.0); - result.append(buffer); - - snprintf(buffer, SIZE, " transaction time: %f us\n", - inTransactionDuration/1000.0); - result.append(buffer); - - /* - * VSYNC state - */ - mEventThread->dump(result, buffer, SIZE); - - /* - * Dump HWComposer state - */ - HWComposer& hwc(hw.getHwComposer()); - snprintf(buffer, SIZE, "h/w composer state:\n"); - result.append(buffer); - snprintf(buffer, SIZE, " h/w composer %s and %s\n", - hwc.initCheck()==NO_ERROR ? "present" : "not present", - (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); - result.append(buffer); - hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); - - /* - * Dump gralloc state - */ - const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); - alloc.dump(result); - hw.dump(result); -} - -status_t SurfaceFlinger::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case CREATE_CONNECTION: - case SET_TRANSACTION_STATE: - case SET_ORIENTATION: - case BOOT_FINISHED: - case TURN_ELECTRON_BEAM_OFF: - case TURN_ELECTRON_BEAM_ON: - { - // codes that require permission check - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - if ((uid != AID_GRAPHICS) && - !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { - ALOGE("Permission Denial: " - "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - break; - } - case CAPTURE_SCREEN: - { - // codes that require permission check - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - if ((uid != AID_GRAPHICS) && - !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { - ALOGE("Permission Denial: " - "can't read framebuffer pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - break; - } - } - - status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); - if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { - CHECK_INTERFACE(ISurfaceComposer, data, reply); - if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - ALOGE("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 - case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE - return NO_ERROR; - case 1002: // SHOW_UPDATES - n = data.readInt32(); - mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); - invalidateHwcGeometry(); - repaintEverything(); - return NO_ERROR; - case 1003: // SHOW_BACKGROUND - n = data.readInt32(); - mDebugBackground = n ? 1 : 0; - return NO_ERROR; - case 1004:{ // repaint everything - repaintEverything(); - return NO_ERROR; - } - case 1005:{ // force transaction - setTransactionFlags(eTransactionNeeded|eTraversalNeeded); - return NO_ERROR; - } - case 1006:{ // send empty update - signalRefresh(); - return NO_ERROR; - } - case 1008: // toggle use of hw composer - n = data.readInt32(); - mDebugDisableHWC = n ? 1 : 0; - invalidateHwcGeometry(); - repaintEverything(); - return NO_ERROR; - case 1009: // toggle use of transform hint - n = data.readInt32(); - mDebugDisableTransformHint = n ? 1 : 0; - invalidateHwcGeometry(); - repaintEverything(); - return NO_ERROR; - case 1010: // interrogate. - reply->writeInt32(0); - reply->writeInt32(0); - reply->writeInt32(mDebugRegion); - reply->writeInt32(mDebugBackground); - reply->writeInt32(mDebugDisableHWC); - return NO_ERROR; - case 1013: { - Mutex::Autolock _l(mStateLock); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - reply->writeInt32(hw.getPageFlipCount()); - } - return NO_ERROR; - } - } - return err; -} - -void SurfaceFlinger::repaintEverything() { - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const Rect bounds(hw.getBounds()); - setInvalidateRegion(Region(bounds)); - signalTransaction(); -} - -void SurfaceFlinger::setInvalidateRegion(const Region& reg) { - Mutex::Autolock _l(mInvalidateLock); - mInvalidateRegion = reg; -} - -Region SurfaceFlinger::getAndClearInvalidateRegion() { - Mutex::Autolock _l(mInvalidateLock); - Region reg(mInvalidateRegion); - mInvalidateRegion.clear(); - return reg; -} - -// --------------------------------------------------------------------------- - -status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy, - GLuint* textureName, GLfloat* uOut, GLfloat* vOut) -{ - Mutex::Autolock _l(mStateLock); - return renderScreenToTextureLocked(dpy, textureName, uOut, vOut); -} - -status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, - GLuint* textureName, GLfloat* uOut, GLfloat* vOut) -{ - if (!GLExtensions::getInstance().haveFramebufferObject()) - return INVALID_OPERATION; - - // get screen geometry - const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); - const uint32_t hw_w = hw.getWidth(); - const uint32_t hw_h = hw.getHeight(); - GLfloat u = 1; - GLfloat v = 1; - - // make sure to clear all GL error flags - while ( glGetError() != GL_NO_ERROR ) ; - - // create a FBO - GLuint name, tname; - glGenTextures(1, &tname); - glBindTexture(GL_TEXTURE_2D, tname); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, - hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - if (glGetError() != GL_NO_ERROR) { - while ( glGetError() != GL_NO_ERROR ) ; - GLint tw = (2 << (31 - clz(hw_w))); - GLint th = (2 << (31 - clz(hw_h))); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, - tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - u = GLfloat(hw_w) / tw; - v = GLfloat(hw_h) / th; - } - glGenFramebuffersOES(1, &name); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); - glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, - GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); - - // redraw the screen entirely... - glDisable(GL_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); - glDisable(GL_SCISSOR_TEST); - glClearColor(0,0,0,1); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); - const size_t count = layers.size(); - for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer(layers[i]); - layer->drawForSreenShot(); - } - - hw.compositionComplete(); - - // back to main framebuffer - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - glDisable(GL_SCISSOR_TEST); - glDeleteFramebuffersOES(1, &name); - - *textureName = tname; - *uOut = u; - *vOut = v; - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - -status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() -{ - // get screen geometry - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t hw_w = hw.getWidth(); - const uint32_t hw_h = hw.getHeight(); - const Region screenBounds(hw.getBounds()); - - GLfloat u, v; - GLuint tname; - status_t result = renderScreenToTextureLocked(0, &tname, &u, &v); - if (result != NO_ERROR) { - return result; - } - - GLfloat vtx[8]; - const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} }; - glBindTexture(GL_TEXTURE_2D, tname); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, vtx); - - /* - * Texture coordinate mapping - * - * u - * 1 +----------+---+ - * | | | | image is inverted - * | V | | w.r.t. the texture - * 1-v +----------+ | coordinates - * | | - * | | - * | | - * 0 +--------------+ - * 0 1 - * - */ - - class s_curve_interpolator { - const float nbFrames, s, v; - public: - s_curve_interpolator(int nbFrames, float s) - : nbFrames(1.0f / (nbFrames-1)), s(s), - v(1.0f + expf(-s + 0.5f*s)) { - } - float operator()(int f) { - const float x = f * nbFrames; - return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; - } - }; - - class v_stretch { - const GLfloat hw_w, hw_h; - public: - v_stretch(uint32_t hw_w, uint32_t hw_h) - : hw_w(hw_w), hw_h(hw_h) { - } - void operator()(GLfloat* vtx, float v) { - const GLfloat w = hw_w + (hw_w * v); - const GLfloat h = hw_h - (hw_h * v); - const GLfloat x = (hw_w - w) * 0.5f; - const GLfloat y = (hw_h - h) * 0.5f; - vtx[0] = x; vtx[1] = y; - vtx[2] = x; vtx[3] = y + h; - vtx[4] = x + w; vtx[5] = y + h; - vtx[6] = x + w; vtx[7] = y; - } - }; - - class h_stretch { - const GLfloat hw_w, hw_h; - public: - h_stretch(uint32_t hw_w, uint32_t hw_h) - : hw_w(hw_w), hw_h(hw_h) { - } - void operator()(GLfloat* vtx, float v) { - const GLfloat w = hw_w - (hw_w * v); - const GLfloat h = 1.0f; - const GLfloat x = (hw_w - w) * 0.5f; - const GLfloat y = (hw_h - h) * 0.5f; - vtx[0] = x; vtx[1] = y; - vtx[2] = x; vtx[3] = y + h; - vtx[4] = x + w; vtx[5] = y + h; - vtx[6] = x + w; vtx[7] = y; - } - }; - - // the full animation is 24 frames - char value[PROPERTY_VALUE_MAX]; - property_get("debug.sf.electron_frames", value, "24"); - int nbFrames = (atoi(value) + 1) >> 1; - if (nbFrames <= 0) // just in case - nbFrames = 24; - - s_curve_interpolator itr(nbFrames, 7.5f); - s_curve_interpolator itg(nbFrames, 8.0f); - s_curve_interpolator itb(nbFrames, 8.5f); - - v_stretch vverts(hw_w, hw_h); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - for (int i=0 ; i<nbFrames ; i++) { - float x, y, w, h; - const float vr = itr(i); - const float vg = itg(i); - const float vb = itb(i); - - // clear screen - glColorMask(1,1,1,1); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_TEXTURE_2D); - - // draw the red plane - vverts(vtx, vr); - glColorMask(1,0,0,1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // draw the green plane - vverts(vtx, vg); - glColorMask(0,1,0,1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // draw the blue plane - vverts(vtx, vb); - glColorMask(0,0,1,1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // draw the white highlight (we use the last vertices) - glDisable(GL_TEXTURE_2D); - glColorMask(1,1,1,1); - glColor4f(vg, vg, vg, 1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - hw.flip(screenBounds); - } - - h_stretch hverts(hw_w, hw_h); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glColorMask(1,1,1,1); - for (int i=0 ; i<nbFrames ; i++) { - const float v = itg(i); - hverts(vtx, v); - glClear(GL_COLOR_BUFFER_BIT); - glColor4f(1-v, 1-v, 1-v, 1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - hw.flip(screenBounds); - } - - glColorMask(1,1,1,1); - glEnable(GL_SCISSOR_TEST); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDeleteTextures(1, &tname); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - return NO_ERROR; -} - -status_t SurfaceFlinger::electronBeamOnAnimationImplLocked() -{ - status_t result = PERMISSION_DENIED; - - if (!GLExtensions::getInstance().haveFramebufferObject()) - return INVALID_OPERATION; - - - // get screen geometry - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - const uint32_t hw_w = hw.getWidth(); - const uint32_t hw_h = hw.getHeight(); - const Region screenBounds(hw.bounds()); - - GLfloat u, v; - GLuint tname; - result = renderScreenToTextureLocked(0, &tname, &u, &v); - if (result != NO_ERROR) { - return result; - } - - GLfloat vtx[8]; - const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; - glBindTexture(GL_TEXTURE_2D, tname); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, vtx); - - class s_curve_interpolator { - const float nbFrames, s, v; - public: - s_curve_interpolator(int nbFrames, float s) - : nbFrames(1.0f / (nbFrames-1)), s(s), - v(1.0f + expf(-s + 0.5f*s)) { - } - float operator()(int f) { - const float x = f * nbFrames; - return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; - } - }; - - class v_stretch { - const GLfloat hw_w, hw_h; - public: - v_stretch(uint32_t hw_w, uint32_t hw_h) - : hw_w(hw_w), hw_h(hw_h) { - } - void operator()(GLfloat* vtx, float v) { - const GLfloat w = hw_w + (hw_w * v); - const GLfloat h = hw_h - (hw_h * v); - const GLfloat x = (hw_w - w) * 0.5f; - const GLfloat y = (hw_h - h) * 0.5f; - vtx[0] = x; vtx[1] = y; - vtx[2] = x; vtx[3] = y + h; - vtx[4] = x + w; vtx[5] = y + h; - vtx[6] = x + w; vtx[7] = y; - } - }; - - class h_stretch { - const GLfloat hw_w, hw_h; - public: - h_stretch(uint32_t hw_w, uint32_t hw_h) - : hw_w(hw_w), hw_h(hw_h) { - } - void operator()(GLfloat* vtx, float v) { - const GLfloat w = hw_w - (hw_w * v); - const GLfloat h = 1.0f; - const GLfloat x = (hw_w - w) * 0.5f; - const GLfloat y = (hw_h - h) * 0.5f; - vtx[0] = x; vtx[1] = y; - vtx[2] = x; vtx[3] = y + h; - vtx[4] = x + w; vtx[5] = y + h; - vtx[6] = x + w; vtx[7] = y; - } - }; - - // the full animation is 12 frames - int nbFrames = 8; - s_curve_interpolator itr(nbFrames, 7.5f); - s_curve_interpolator itg(nbFrames, 8.0f); - s_curve_interpolator itb(nbFrames, 8.5f); - - h_stretch hverts(hw_w, hw_h); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glColorMask(1,1,1,1); - for (int i=nbFrames-1 ; i>=0 ; i--) { - const float v = itg(i); - hverts(vtx, v); - glClear(GL_COLOR_BUFFER_BIT); - glColor4f(1-v, 1-v, 1-v, 1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - hw.flip(screenBounds); - } - - nbFrames = 4; - v_stretch vverts(hw_w, hw_h); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - for (int i=nbFrames-1 ; i>=0 ; i--) { - float x, y, w, h; - const float vr = itr(i); - const float vg = itg(i); - const float vb = itb(i); - - // clear screen - glColorMask(1,1,1,1); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_TEXTURE_2D); - - // draw the red plane - vverts(vtx, vr); - glColorMask(1,0,0,1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // draw the green plane - vverts(vtx, vg); - glColorMask(0,1,0,1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // draw the blue plane - vverts(vtx, vb); - glColorMask(0,0,1,1); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - hw.flip(screenBounds); - } - - glColorMask(1,1,1,1); - glEnable(GL_SCISSOR_TEST); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDeleteTextures(1, &tname); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - -status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) -{ - DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); - if (!hw.canDraw()) { - // we're already off - return NO_ERROR; - } - - // turn off hwc while we're doing the animation - hw.getHwComposer().disable(); - // and make sure to turn it back on (if needed) next time we compose - invalidateHwcGeometry(); - - if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { - electronBeamOffAnimationImplLocked(); - } - - // always clear the whole screen at the end of the animation - glClearColor(0,0,0,1); - glDisable(GL_SCISSOR_TEST); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - hw.flip( Region(hw.bounds()) ); - - return NO_ERROR; -} - -status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) -{ - class MessageTurnElectronBeamOff : public MessageBase { - SurfaceFlinger* flinger; - int32_t mode; - status_t result; - public: - MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) - : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { - } - status_t getResult() const { - return result; - } - virtual bool handler() { - Mutex::Autolock _l(flinger->mStateLock); - result = flinger->turnElectronBeamOffImplLocked(mode); - return true; - } - }; - - sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); - status_t res = postMessageSync(msg); - if (res == NO_ERROR) { - res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); - - // work-around: when the power-manager calls us we activate the - // animation. eventually, the "on" animation will be called - // by the power-manager itself - mElectronBeamAnimationMode = mode; - } - return res; -} - -// --------------------------------------------------------------------------- - -status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) -{ - DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); - if (hw.canDraw()) { - // we're already on - return NO_ERROR; - } - if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { - electronBeamOnAnimationImplLocked(); - } - - // make sure to redraw the whole screen when the animation is done - mDirtyRegion.set(hw.bounds()); - signalTransaction(); - - return NO_ERROR; -} - -status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) -{ - class MessageTurnElectronBeamOn : public MessageBase { - SurfaceFlinger* flinger; - int32_t mode; - status_t result; - public: - MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) - : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { - } - status_t getResult() const { - return result; - } - virtual bool handler() { - Mutex::Autolock _l(flinger->mStateLock); - result = flinger->turnElectronBeamOnImplLocked(mode); - return true; - } - }; - - postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - -status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, - sp<IMemoryHeap>* heap, - uint32_t* w, uint32_t* h, PixelFormat* f, - uint32_t sw, uint32_t sh, - uint32_t minLayerZ, uint32_t maxLayerZ) -{ - status_t result = PERMISSION_DENIED; - - // only one display supported for now - if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) - return BAD_VALUE; - - if (!GLExtensions::getInstance().haveFramebufferObject()) - return INVALID_OPERATION; - - // get screen geometry - const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); - const uint32_t hw_w = hw.getWidth(); - const uint32_t hw_h = hw.getHeight(); - - if ((sw > hw_w) || (sh > hw_h)) - return BAD_VALUE; - - sw = (!sw) ? hw_w : sw; - sh = (!sh) ? hw_h : sh; - const size_t size = sw * sh * 4; - - //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", - // sw, sh, minLayerZ, maxLayerZ); - - // make sure to clear all GL error flags - while ( glGetError() != GL_NO_ERROR ) ; - - // create a FBO - GLuint name, tname; - glGenRenderbuffersOES(1, &tname); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); - glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); - glGenFramebuffersOES(1, &name); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, - GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); - - GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); - - if (status == GL_FRAMEBUFFER_COMPLETE_OES) { - - // invert everything, b/c glReadPixel() below will invert the FB - glViewport(0, 0, sw, sh); - glScissor(0, 0, sw, sh); - glEnable(GL_SCISSOR_TEST); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrthof(0, hw_w, hw_h, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - - // redraw the screen entirely... - glClearColor(0,0,0,1); - glClear(GL_COLOR_BUFFER_BIT); - - const LayerVector& layers(mDrawingState.layersSortedByZ); - const size_t count = layers.size(); - for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer(layers[i]); - const uint32_t flags = layer->drawingState().flags; - if (!(flags & ISurfaceComposer::eLayerHidden)) { - const uint32_t z = layer->drawingState().z; - if (z >= minLayerZ && z <= maxLayerZ) { - layer->drawForSreenShot(); - } - } - } - - // XXX: this is needed on tegra - glEnable(GL_SCISSOR_TEST); - glScissor(0, 0, sw, sh); - - // check for errors and return screen capture - if (glGetError() != GL_NO_ERROR) { - // error while rendering - result = INVALID_OPERATION; - } else { - // allocate shared memory large enough to hold the - // screen capture - sp<MemoryHeapBase> base( - new MemoryHeapBase(size, 0, "screen-capture") ); - void* const ptr = base->getBase(); - if (ptr) { - // capture the screen with glReadPixels() - glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); - if (glGetError() == GL_NO_ERROR) { - *heap = base; - *w = sw; - *h = sh; - *f = PIXEL_FORMAT_RGBA_8888; - result = NO_ERROR; - } - } else { - result = NO_MEMORY; - } - } - glEnable(GL_SCISSOR_TEST); - glViewport(0, 0, hw_w, hw_h); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } else { - result = BAD_VALUE; - } - - // release FBO resources - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - glDeleteRenderbuffersOES(1, &tname); - glDeleteFramebuffersOES(1, &name); - - hw.compositionComplete(); - - // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); - - return result; -} - - -status_t SurfaceFlinger::captureScreen(DisplayID dpy, - sp<IMemoryHeap>* heap, - uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t sw, uint32_t sh, - uint32_t minLayerZ, uint32_t maxLayerZ) -{ - // only one display supported for now - if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) - return BAD_VALUE; - - if (!GLExtensions::getInstance().haveFramebufferObject()) - return INVALID_OPERATION; - - class MessageCaptureScreen : public MessageBase { - SurfaceFlinger* flinger; - DisplayID dpy; - sp<IMemoryHeap>* heap; - uint32_t* w; - uint32_t* h; - PixelFormat* f; - uint32_t sw; - uint32_t sh; - uint32_t minLayerZ; - uint32_t maxLayerZ; - status_t result; - public: - MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, - sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, - uint32_t sw, uint32_t sh, - uint32_t minLayerZ, uint32_t maxLayerZ) - : flinger(flinger), dpy(dpy), - heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), - minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), - result(PERMISSION_DENIED) - { - } - status_t getResult() const { - return result; - } - virtual bool handler() { - Mutex::Autolock _l(flinger->mStateLock); - - // if we have secure windows, never allow the screen capture - if (flinger->mSecureFrameBuffer) - return true; - - result = flinger->captureScreenImplLocked(dpy, - heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); - - return true; - } - }; - - sp<MessageBase> msg = new MessageCaptureScreen(this, - dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); - status_t res = postMessageSync(msg); - if (res == NO_ERROR) { - res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); - } - return res; -} - -// --------------------------------------------------------------------------- - -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; -} - -size_t Client::attachLayer(const sp<LayerBaseClient>& layer) -{ - Mutex::Autolock _l(mLock); - size_t name = mNameGenerator++; - mLayers.add(name, layer); - return name; -} - -void Client::detachLayer(const LayerBaseClient* layer) -{ - Mutex::Autolock _l(mLock); - // 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 -{ - Mutex::Autolock _l(mLock); - sp<LayerBaseClient> lbc; - wp<LayerBaseClient> layer(mLayers.valueFor(i)); - if (layer != 0) { - lbc = layer.promote(); - ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); - } - return lbc; -} - - -status_t Client::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - // these must be checked - IPCThreadState* ipc = IPCThreadState::self(); - const int pid = ipc->getCallingPid(); - const int uid = ipc->getCallingUid(); - const int self_pid = getpid(); - if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { - // we're called from a different process, do the real check - if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) - { - ALOGE("Permission Denial: " - "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - } - return BnSurfaceComposerClient::onTransact(code, data, reply, flags); -} - - -sp<ISurface> Client::createSurface( - ISurfaceComposerClient::surface_data_t* params, - const String8& name, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) -{ - /* - * createSurface must be called from the GL thread so that it can - * have access to the GL context. - */ - - class MessageCreateSurface : public MessageBase { - sp<ISurface> result; - SurfaceFlinger* flinger; - ISurfaceComposerClient::surface_data_t* params; - Client* client; - const String8& name; - DisplayID display; - uint32_t w, h; - PixelFormat format; - uint32_t flags; - public: - MessageCreateSurface(SurfaceFlinger* flinger, - ISurfaceComposerClient::surface_data_t* params, - const String8& name, Client* client, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags) - : flinger(flinger), params(params), client(client), name(name), - display(display), w(w), h(h), format(format), flags(flags) - { - } - sp<ISurface> getResult() const { return result; } - virtual bool handler() { - result = flinger->createSurface(params, name, client, - display, w, h, format, flags); - return true; - } - }; - - sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), - params, name, this, display, w, h, format, flags); - mFlinger->postMessageSync(msg); - return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); -} -status_t Client::destroySurface(SurfaceID sid) { - return mFlinger->removeSurface(this, sid); -} - -// --------------------------------------------------------------------------- - -GraphicBufferAlloc::GraphicBufferAlloc() {} - -GraphicBufferAlloc::~GraphicBufferAlloc() {} - -sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage, status_t* error) { - sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); - status_t err = graphicBuffer->initCheck(); - *error = err; - if (err != 0 || graphicBuffer->handle == 0) { - if (err == NO_MEMORY) { - GraphicBuffer::dumpAllocationsToSystemLog(); - } - ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " - "failed (%s), handle=%p", - w, h, strerror(-err), graphicBuffer->handle); - return 0; - } - return graphicBuffer; -} - -// --------------------------------------------------------------------------- - -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; -} - -DisplayHardware& GraphicPlane::editDisplayHardware() { - return *mHw; -} - -const Transform& GraphicPlane::transform() const { - return mGlobalTransform; -} - -EGLDisplay GraphicPlane::getEGLDisplay() const { - return mHw->getEGLDisplay(); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h deleted file mode 100644 index b507877..0000000 --- a/services/surfaceflinger/SurfaceFlinger.h +++ /dev/null @@ -1,428 +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 <cutils/compiler.h> - -#include <utils/Atomic.h> -#include <utils/Errors.h> -#include <utils/KeyedVector.h> -#include <utils/RefBase.h> -#include <utils/SortedVector.h> -#include <utils/threads.h> - -#include <binder/BinderService.h> -#include <binder/IMemory.h> - -#include <ui/PixelFormat.h> -#include <gui/IGraphicBufferAlloc.h> -#include <gui/ISurfaceComposer.h> -#include <gui/ISurfaceComposerClient.h> - -#include "Barrier.h" -#include "Layer.h" - -#include "MessageQueue.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class Client; -class DisplayHardware; -class DisplayEventConnection; -class EventThread; -class Layer; -class LayerDim; -class LayerScreenshot; -struct surface_flinger_cblk_t; - -// --------------------------------------------------------------------------- - -class Client : public BnSurfaceComposerClient -{ -public: - Client(const sp<SurfaceFlinger>& flinger); - ~Client(); - - status_t initCheck() const; - - // protected by SurfaceFlinger::mStateLock - size_t attachLayer(const sp<LayerBaseClient>& layer); - void detachLayer(const LayerBaseClient* layer); - sp<LayerBaseClient> getLayerUser(int32_t i) const; - -private: - // ISurfaceComposerClient interface - virtual sp<ISurface> createSurface( - surface_data_t* params, 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 onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); - - // constant - sp<SurfaceFlinger> mFlinger; - - // protected by mLock - DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers; - size_t mNameGenerator; - - // thread-safe - mutable Mutex mLock; -}; - -class GraphicBufferAlloc : public BnGraphicBufferAlloc -{ -public: - GraphicBufferAlloc(); - virtual ~GraphicBufferAlloc(); - virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage, status_t* error); -}; - -// --------------------------------------------------------------------------- - -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; - DisplayHardware& editDisplayHardware(); - 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 BinderService<SurfaceFlinger>, - public BnSurfaceComposer, - public IBinder::DeathRecipient, - protected Thread -{ -public: - static char const* getServiceName() { return "SurfaceFlinger"; } - - 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<IGraphicBufferAlloc> createGraphicBufferAlloc(); - virtual sp<IMemoryHeap> getCblk() const; - virtual void bootFinished(); - virtual void setTransactionState(const Vector<ComposerState>& state, - int orientation, uint32_t flags); - virtual bool authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const; - virtual sp<IDisplayEventConnection> createDisplayEventConnection(); - - virtual status_t captureScreen(DisplayID dpy, - sp<IMemoryHeap>* heap, - uint32_t* width, uint32_t* height, - PixelFormat* format, uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ); - - virtual status_t turnElectronBeamOff(int32_t mode); - virtual status_t turnElectronBeamOn(int32_t mode); - - void screenReleased(DisplayID dpy); - void screenAcquired(DisplayID dpy); - - status_t renderScreenToTexture(DisplayID dpy, - GLuint* textureName, GLfloat* uOut, GLfloat* vOut); - status_t renderScreenToTextureLocked(DisplayID dpy, - GLuint* textureName, GLfloat* uOut, GLfloat* vOut); - - void onMessageReceived(int32_t what); - - 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); - - status_t removeLayer(const sp<LayerBase>& layer); - status_t addLayer(const sp<LayerBase>& layer); - status_t invalidateLayerVisibility(const sp<LayerBase>& layer); - void invalidateHwcGeometry(); - - sp<Layer> getLayer(const sp<ISurface>& sur) const; - - GLuint getProtectedTexName() const { return mProtectedTexName; } - - - class MessageDestroyGLTexture : public MessageBase { - GLuint texture; - public: - MessageDestroyGLTexture(GLuint texture) : texture(texture) { } - virtual bool handler() { - glDeleteTextures(1, &texture); - return true; - } - }; - - -private: - // DeathRecipient interface - virtual void binderDied(const wp<IBinder>& who); - -private: - friend class Client; - friend class DisplayEventConnection; - friend class LayerBase; - friend class LayerBaseClient; - friend class Layer; - - sp<ISurface> createSurface( - ISurfaceComposerClient::surface_data_t* params, - const String8& name, - const sp<Client>& client, - 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<LayerDim> createDimSurface( - const sp<Client>& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); - - sp<LayerScreenshot> createScreenshotSurface( - 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 wp<LayerBaseClient>& layer); - uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s); - - class LayerVector : public SortedVector< sp<LayerBase> > { - public: - LayerVector() { } - LayerVector(const LayerVector& rhs) : SortedVector< sp<LayerBase> >(rhs) { } - virtual int do_compare(const void* lhs, const void* rhs) const { - const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); - const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); - // sort layers by Z order - uint32_t lz = l->currentState().z; - uint32_t rz = r->currentState().z; - // then by sequence, so we get a stable ordering - return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence); - } - }; - - struct State { - State() { - orientation = ISurfaceComposer::eOrientationDefault; - } - LayerVector layersSortedByZ; - uint8_t orientation; - uint8_t orientationFlags; - }; - - 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); - - void signalTransaction(); - void signalLayerUpdate(); - void signalRefresh(); - void repaintEverything(); - -private: - void waitForEvent(); - void handleConsoleEvents(); - void handleTransaction(uint32_t transactionFlags); - void handleTransactionLocked(uint32_t transactionFlags); - - void computeVisibleRegions( - const LayerVector& currentLayers, - Region& dirtyRegion, - Region& wormholeRegion); - - void handlePageFlip(); - bool lockPageFlip(const LayerVector& currentLayers); - void unlockPageFlip(const LayerVector& currentLayers); - void handleRefresh(); - void handleWorkList(); - void handleRepaint(); - void postFramebuffer(); - void setupHardwareComposer(Region& dirtyInOut); - void composeSurfaces(const Region& dirty); - - - void setInvalidateRegion(const Region& reg); - Region getAndClearInvalidateRegion(); - - 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 peekTransactionFlags(uint32_t flags); - uint32_t setTransactionFlags(uint32_t flags); - void commitTransaction(); - - - status_t captureScreenImplLocked(DisplayID dpy, - sp<IMemoryHeap>* heap, - uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ); - - status_t turnElectronBeamOffImplLocked(int32_t mode); - status_t turnElectronBeamOnImplLocked(int32_t mode); - status_t electronBeamOffAnimationImplLocked(); - status_t electronBeamOnAnimationImplLocked(); - - void debugFlashRegions(); - void drawWormhole() const; - - void listLayersLocked(const Vector<String16>& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const; - void dumpStatsLocked(const Vector<String16>& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const; - void clearStatsLocked(const Vector<String16>& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const; - void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const; - - mutable MessageQueue mEventQueue; - - // access must be protected by mStateLock - mutable Mutex mStateLock; - State mCurrentState; - volatile int32_t mTransactionFlags; - Condition mTransactionCV; - SortedVector< sp<LayerBase> > mLayerPurgatory; - bool mTransationPending; - Vector< sp<LayerBase> > mLayersPendingRemoval; - - // protected by mStateLock (but we could use another lock) - GraphicPlane mGraphicPlanes[1]; - bool mLayersRemoved; - DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap; - - // access must be protected by mInvalidateLock - mutable Mutex mInvalidateLock; - Region mInvalidateRegion; - - // constant members (no synchronization needed for access) - sp<IMemoryHeap> mServerHeap; - surface_flinger_cblk_t* mServerCblk; - GLuint mWormholeTexName; - GLuint mProtectedTexName; - nsecs_t mBootTime; - sp<EventThread> mEventThread; - - // Can only accessed from the main thread, these members - // don't need synchronization - State mDrawingState; - Region mDirtyRegion; - Region mDirtyRegionRemovedLayer; - Region mSwapRegion; - Region mWormholeRegion; - bool mVisibleRegionsDirty; - bool mHwWorkListDirty; - int32_t mElectronBeamAnimationMode; - Vector< sp<LayerBase> > mVisibleLayersSortedByZ; - - - // don't use a lock for these, we don't care - int mDebugRegion; - int mDebugBackground; - int mDebugDDMS; - int mDebugDisableHWC; - int mDebugDisableTransformHint; - volatile nsecs_t mDebugInSwapBuffers; - nsecs_t mLastSwapBufferTime; - volatile nsecs_t mDebugInTransaction; - nsecs_t mLastTransactionTime; - bool mBootFinished; - - // these are thread safe - mutable Barrier mReadyToRunBarrier; - - - // protected by mDestroyedLayerLock; - mutable Mutex mDestroyedLayerLock; - Vector<LayerBase const *> mDestroyedLayers; - - // 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; -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SURFACE_FLINGER_H diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp deleted file mode 100644 index 49e8e63..0000000 --- a/services/surfaceflinger/SurfaceTextureLayer.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2011 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 "Layer.h" -#include "SurfaceTextureLayer.h" - -namespace android { -// --------------------------------------------------------------------------- - - -SurfaceTextureLayer::SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer) - : SurfaceTexture(tex, true, GL_TEXTURE_EXTERNAL_OES, false), mLayer(layer) { -} - -SurfaceTextureLayer::~SurfaceTextureLayer() { -} - - -status_t SurfaceTextureLayer::setDefaultBufferSize(uint32_t w, uint32_t h) -{ - //ALOGD("%s, w=%u, h=%u", __PRETTY_FUNCTION__, w, h); - return SurfaceTexture::setDefaultBufferSize(w, h); -} - -status_t SurfaceTextureLayer::setDefaultBufferFormat(uint32_t format) -{ - mDefaultFormat = format; - return NO_ERROR; -} - -status_t SurfaceTextureLayer::setBufferCount(int bufferCount) { - status_t res = SurfaceTexture::setBufferCount(bufferCount); - return res; -} - -status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp, - uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { - - status_t res = SurfaceTexture::queueBuffer(buf, timestamp, - outWidth, outHeight, outTransform); - sp<Layer> layer(mLayer.promote()); - if (layer != NULL) { - *outTransform = layer->getTransformHint(); - } - return res; -} - -status_t SurfaceTextureLayer::dequeueBuffer(int *buf, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { - - status_t res(NO_INIT); - sp<Layer> layer(mLayer.promote()); - if (layer != NULL) { - if (format == 0) - format = mDefaultFormat; - uint32_t effectiveUsage = layer->getEffectiveUsage(usage); - //ALOGD("%s, w=%u, h=%u, format=%u, usage=%08x, effectiveUsage=%08x", - // __PRETTY_FUNCTION__, w, h, format, usage, effectiveUsage); - res = SurfaceTexture::dequeueBuffer(buf, w, h, format, effectiveUsage); - } - return res; -} - -status_t SurfaceTextureLayer::connect(int api, - uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { - status_t err = SurfaceTexture::connect(api, - outWidth, outHeight, outTransform); - if (err == NO_ERROR) { - sp<Layer> layer(mLayer.promote()); - if (layer != NULL) { - uint32_t orientation = layer->getOrientation(); - if (orientation & Transform::ROT_INVALID) { - orientation = 0; - } - *outTransform = orientation; - } - switch(api) { - case NATIVE_WINDOW_API_CPU: - // SurfaceTextureClient supports only 2 buffers for CPU connections - this->setBufferCountServer(2); - break; - case NATIVE_WINDOW_API_MEDIA: - case NATIVE_WINDOW_API_CAMERA: - // Camera preview and videos are rate-limited on the producer - // side. If enabled for this build, we use async mode to always - // show the most recent frame at the cost of requiring an - // additional buffer. -#ifndef NEVER_DEFAULT_TO_ASYNC_MODE - err = setSynchronousMode(false); - break; -#endif - // fall through to set synchronous mode when not defaulting to - // async mode. - deafult: - err = setSynchronousMode(true); - break; - } - if (err != NO_ERROR) { - disconnect(api); - } - } - return err; -} - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h deleted file mode 100644 index 9508524..0000000 --- a/services/surfaceflinger/SurfaceTextureLayer.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2011 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_TEXTURE_LAYER_H -#define ANDROID_SURFACE_TEXTURE_LAYER_H - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <gui/SurfaceTexture.h> - -namespace android { -// --------------------------------------------------------------------------- - -class Layer; - -class SurfaceTextureLayer : public SurfaceTexture -{ - wp<Layer> mLayer; - uint32_t mDefaultFormat; - -public: - SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer); - ~SurfaceTextureLayer(); - - status_t setDefaultBufferSize(uint32_t w, uint32_t h); - status_t setDefaultBufferFormat(uint32_t format); - -public: - virtual status_t setBufferCount(int bufferCount); - -protected: - virtual status_t queueBuffer(int buf, int64_t timestamp, - uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); - - virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h, - uint32_t format, uint32_t usage); - - virtual status_t connect(int api, - uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform); -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SURFACE_TEXTURE_LAYER_H diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp deleted file mode 100644 index ca3fa6e..0000000 --- a/services/surfaceflinger/Transform.cpp +++ /dev/null @@ -1,355 +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 "clz.h" -#include "Transform.h" - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -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; -} - -float Transform::tx() const { - return mMatrix[2][0]; -} - -float Transform::ty() const { - return mMatrix[2][1]; -} - -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; - } - - Transform H, V, R; - if (flags & ROT_90) { - // w & h are inverted when rotating by 90 degrees - swap(w, h); - } - - if (flags & FLIP_H) { - H.mType = (FLIP_H << 8) | SCALE; - H.mType |= isZero(w) ? IDENTITY : TRANSLATE; - mat33& M(H.mMatrix); - M[0][0] = -1; - M[2][0] = w; - } - - if (flags & FLIP_V) { - V.mType = (FLIP_V << 8) | SCALE; - V.mType |= isZero(h) ? IDENTITY : TRANSLATE; - mat33& M(V.mMatrix); - M[1][1] = -1; - M[2][1] = h; - } - - if (flags & ROT_90) { - const float original_w = h; - R.mType = (ROT_90 << 8) | ROTATE; - R.mType |= isZero(original_w) ? IDENTITY : TRANSLATE; - mat33& M(R.mMatrix); - M[0][0] = 0; M[1][0] =-1; M[2][0] = original_w; - M[0][1] = 1; M[1][1] = 0; - } - - *this = (R*(H*V)); - 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 { - int xpos = floorf(tx() + 0.5f); - int ypos = floorf(ty() + 0.5f); - out = reg.translate(xpos, ypos); - } - 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_V; - if (c<0) flags |= FLIP_H; - if (!absIsOne(b) || !absIsOne(c)) { - scale = true; - } - } else { - // there is a skew component and/or a non 90 degrees rotation - 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 (getOrientation() & 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 "); - - ALOGD("%s 0x%08x (%s, %s)", name, mType, flags.string(), type.string()); - ALOGD("%.4f %.4f %.4f", m[0][0], m[1][0], m[2][0]); - ALOGD("%.4f %.4f %.4f", m[0][1], m[1][1], m[2][1]); - ALOGD("%.4f %.4f %.4f", m[0][2], m[1][2], m[2][2]); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h deleted file mode 100644 index ec74243..0000000 --- a/services/surfaceflinger/Transform.h +++ /dev/null @@ -1,127 +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> - -#include <hardware/hardware.h> - -namespace android { - -class Region; - -// --------------------------------------------------------------------------- - -class Transform -{ -public: - Transform(); - Transform(const Transform& other); - explicit Transform(uint32_t orientation); - ~Transform(); - - enum orientation_flags { - ROT_0 = 0x00000000, - FLIP_H = HAL_TRANSFORM_FLIP_H, - FLIP_V = HAL_TRANSFORM_FLIP_V, - ROT_90 = HAL_TRANSFORM_ROT_90, - 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 - float tx() const; - float 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/services/surfaceflinger/clz.cpp b/services/surfaceflinger/clz.cpp deleted file mode 100644 index 2456b86..0000000 --- a/services/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/services/surfaceflinger/clz.h b/services/surfaceflinger/clz.h deleted file mode 100644 index a4c5262..0000000 --- a/services/surfaceflinger/clz.h +++ /dev/null @@ -1,64 +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 inline clz(int32_t x) { - return __builtin_clz(x); -} - -template <typename T> -static inline T min(T a, T b) { - return a<b ? a : b; -} -template <typename T> -static inline T min(T a, T b, T c) { - return min(a, min(b, c)); -} -template <typename T> -static inline T min(T a, T b, T c, T d) { - return min(a, b, min(c, d)); -} - -template <typename T> -static inline T max(T a, T b) { - return a>b ? a : b; -} -template <typename T> -static inline T max(T a, T b, T c) { - return max(a, max(b, c)); -} -template <typename T> -static inline T max(T a, T b, T c, T d) { - return max(a, b, max(c, d)); -} - -template <typename T> -static inline -void swap(T& a, T& b) { - T t(a); - a = b; - b = t; -} - - -}; // namespace android - -#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */ diff --git a/services/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk deleted file mode 100644 index b655648..0000000 --- a/services/surfaceflinger/tests/Android.mk +++ /dev/null @@ -1,40 +0,0 @@ -# Build the unit tests, -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := SurfaceFlinger_test - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := \ - Transaction_test.cpp \ - -LOCAL_SHARED_LIBRARIES := \ - libEGL \ - libGLESv2 \ - libandroid \ - libbinder \ - libcutils \ - libgui \ - libstlport \ - libui \ - libutils \ - -LOCAL_C_INCLUDES := \ - bionic \ - bionic/libstdc++/include \ - external/gtest/include \ - external/stlport/stlport \ - -# Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) -# to integrate with auto-test framework. -include $(BUILD_NATIVE_TEST) - -# Include subdirectory makefiles -# ============================================================ - -# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework -# team really wants is to build the stuff defined by this makefile. -ifeq (,$(ONE_SHOT_MAKEFILE)) -include $(call first-makefiles-under,$(LOCAL_PATH)) -endif diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp deleted file mode 100644 index 84ae0d9..0000000 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2011 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 <gtest/gtest.h> - -#include <binder/IMemory.h> - -#include <gui/ISurfaceComposer.h> -#include <gui/Surface.h> -#include <gui/SurfaceComposerClient.h> -#include <private/gui/ComposerService.h> - -#include <utils/String8.h> - -namespace android { - -// Fill an RGBA_8888 formatted surface with a single color. -static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, - uint8_t r, uint8_t g, uint8_t b) { - Surface::SurfaceInfo info; - sp<Surface> s = sc->getSurface(); - ASSERT_TRUE(s != NULL); - ASSERT_EQ(NO_ERROR, s->lock(&info)); - uint8_t* img = reinterpret_cast<uint8_t*>(info.bits); - for (uint32_t y = 0; y < info.h; y++) { - for (uint32_t x = 0; x < info.w; x++) { - uint8_t* pixel = img + (4 * (y*info.s + x)); - pixel[0] = r; - pixel[1] = g; - pixel[2] = b; - pixel[3] = 255; - } - } - ASSERT_EQ(NO_ERROR, s->unlockAndPost()); -} - -// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check -// individual pixel values for testing purposes. -class ScreenCapture : public RefBase { -public: - static void captureScreen(sp<ScreenCapture>* sc) { - sp<IMemoryHeap> heap; - uint32_t w=0, h=0; - PixelFormat fmt=0; - sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 0, 0, - 0, INT_MAX)); - ASSERT_TRUE(heap != NULL); - ASSERT_EQ(PIXEL_FORMAT_RGBA_8888, fmt); - *sc = new ScreenCapture(w, h, heap); - } - - void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) { - const uint8_t* img = reinterpret_cast<const uint8_t*>(mHeap->base()); - const uint8_t* pixel = img + (4 * (y*mWidth + x)); - if (r != pixel[0] || g != pixel[1] || b != pixel[2]) { - String8 err(String8::format("pixel @ (%3d, %3d): " - "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]", - x, y, r, g, b, pixel[0], pixel[1], pixel[2])); - EXPECT_EQ(String8(), err); - } - } - -private: - ScreenCapture(uint32_t w, uint32_t h, const sp<IMemoryHeap>& heap) : - mWidth(w), - mHeight(h), - mHeap(heap) - {} - - const uint32_t mWidth; - const uint32_t mHeight; - sp<IMemoryHeap> mHeap; -}; - -class LayerUpdateTest : public ::testing::Test { -protected: - virtual void SetUp() { - mComposerClient = new SurfaceComposerClient; - ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); - - ssize_t displayWidth = mComposerClient->getDisplayWidth(0); - ssize_t displayHeight = mComposerClient->getDisplayHeight(0); - - // Background surface - mBGSurfaceControl = mComposerClient->createSurface( - String8("BG Test Surface"), 0, displayWidth, displayHeight, - PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mBGSurfaceControl != NULL); - ASSERT_TRUE(mBGSurfaceControl->isValid()); - fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195); - - // Foreground surface - mFGSurfaceControl = mComposerClient->createSurface( - String8("FG Test Surface"), 0, 64, 64, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mFGSurfaceControl != NULL); - ASSERT_TRUE(mFGSurfaceControl->isValid()); - - fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63); - - // Synchronization surface - mSyncSurfaceControl = mComposerClient->createSurface( - String8("Sync Test Surface"), 0, 1, 1, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mSyncSurfaceControl != NULL); - ASSERT_TRUE(mSyncSurfaceControl->isValid()); - - fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - - SurfaceComposerClient::openGlobalTransaction(); - - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT_MAX-2)); - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show()); - - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX-1)); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64)); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); - - ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setLayer(INT_MAX-1)); - ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setPosition(displayWidth-2, - displayHeight-2)); - ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->show()); - - SurfaceComposerClient::closeGlobalTransaction(true); - } - - virtual void TearDown() { - mComposerClient->dispose(); - mBGSurfaceControl = 0; - mFGSurfaceControl = 0; - mSyncSurfaceControl = 0; - mComposerClient = 0; - } - - void waitForPostedBuffers() { - // Since the sync surface is in synchronous mode (i.e. double buffered) - // posting three buffers to it should ensure that at least two - // SurfaceFlinger::handlePageFlip calls have been made, which should - // guaranteed that a buffer posted to another Surface has been retired. - fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - } - - sp<SurfaceComposerClient> mComposerClient; - sp<SurfaceControl> mBGSurfaceControl; - sp<SurfaceControl> mFGSurfaceControl; - - // This surface is used to ensure that the buffers posted to - // mFGSurfaceControl have been picked up by SurfaceFlinger. - sp<SurfaceControl> mSyncSurfaceControl; -}; - -TEST_F(LayerUpdateTest, LayerMoveWorks) { - sp<ScreenCapture> sc; - { - SCOPED_TRACE("before move"); - ScreenCapture::captureScreen(&sc); - sc->checkPixel( 0, 12, 63, 63, 195); - sc->checkPixel( 75, 75, 195, 63, 63); - sc->checkPixel(145, 145, 63, 63, 195); - } - - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128)); - SurfaceComposerClient::closeGlobalTransaction(true); - { - // This should reflect the new position, but not the new color. - SCOPED_TRACE("after move, before redraw"); - ScreenCapture::captureScreen(&sc); - sc->checkPixel( 24, 24, 63, 63, 195); - sc->checkPixel( 75, 75, 63, 63, 195); - sc->checkPixel(145, 145, 195, 63, 63); - } - - fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63); - waitForPostedBuffers(); - { - // This should reflect the new position and the new color. - SCOPED_TRACE("after redraw"); - ScreenCapture::captureScreen(&sc); - sc->checkPixel( 24, 24, 63, 63, 195); - sc->checkPixel( 75, 75, 63, 63, 195); - sc->checkPixel(145, 145, 63, 195, 63); - } -} - -TEST_F(LayerUpdateTest, LayerResizeWorks) { - sp<ScreenCapture> sc; - { - SCOPED_TRACE("before resize"); - ScreenCapture::captureScreen(&sc); - sc->checkPixel( 0, 12, 63, 63, 195); - sc->checkPixel( 75, 75, 195, 63, 63); - sc->checkPixel(145, 145, 63, 63, 195); - } - - ALOGD("resizing"); - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128)); - SurfaceComposerClient::closeGlobalTransaction(true); - ALOGD("resized"); - { - // This should not reflect the new size or color because SurfaceFlinger - // has not yet received a buffer of the correct size. - SCOPED_TRACE("after resize, before redraw"); - ScreenCapture::captureScreen(&sc); - sc->checkPixel( 0, 12, 63, 63, 195); - sc->checkPixel( 75, 75, 195, 63, 63); - sc->checkPixel(145, 145, 63, 63, 195); - } - - ALOGD("drawing"); - fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63); - waitForPostedBuffers(); - ALOGD("drawn"); - { - // This should reflect the new size and the new color. - SCOPED_TRACE("after redraw"); - ScreenCapture::captureScreen(&sc); - sc->checkPixel( 24, 24, 63, 63, 195); - sc->checkPixel( 75, 75, 63, 195, 63); - sc->checkPixel(145, 145, 63, 195, 63); - } -} - -} diff --git a/services/surfaceflinger/tests/resize/Android.mk b/services/surfaceflinger/tests/resize/Android.mk deleted file mode 100644 index d81679e..0000000 --- a/services/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 \ - libgui - -LOCAL_MODULE:= test-resize - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp deleted file mode 100644 index c143b3d..0000000 --- a/services/surfaceflinger/tests/resize/resize.cpp +++ /dev/null @@ -1,67 +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 <cutils/memory.h> - -#include <utils/Log.h> - -#include <binder/IPCThreadState.h> -#include <binder/ProcessState.h> -#include <binder/IServiceManager.h> - -#include <gui/Surface.h> -#include <gui/SurfaceComposerClient.h> - -using namespace android; - -namespace android { - -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(); - - sp<Surface> surface = client->createSurface(0, 160, 240, - PIXEL_FORMAT_RGB_565); - - - SurfaceComposerClient::openGlobalTransaction(); - surface->setLayer(100000); - SurfaceComposerClient::closeGlobalTransaction(); - - 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(); - - SurfaceComposerClient::openGlobalTransaction(); - surface->setSize(320, 240); - SurfaceComposerClient::closeGlobalTransaction(); - - - IPCThreadState::self()->joinThreadPool(); - - return 0; -} diff --git a/services/surfaceflinger/tests/screencap/Android.mk b/services/surfaceflinger/tests/screencap/Android.mk deleted file mode 100644 index 5cdd1a8..0000000 --- a/services/surfaceflinger/tests/screencap/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - screencap.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libbinder \ - libskia \ - libui \ - libgui - -LOCAL_MODULE:= test-screencap - -LOCAL_MODULE_TAGS := tests - -LOCAL_C_INCLUDES += \ - external/skia/include/core \ - external/skia/include/effects \ - external/skia/include/images \ - external/skia/src/ports \ - external/skia/include/utils - -include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/screencap/screencap.cpp b/services/surfaceflinger/tests/screencap/screencap.cpp deleted file mode 100644 index 53566e0..0000000 --- a/services/surfaceflinger/tests/screencap/screencap.cpp +++ /dev/null @@ -1,63 +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 <utils/Log.h> - -#include <binder/IPCThreadState.h> -#include <binder/ProcessState.h> -#include <binder/IServiceManager.h> - -#include <binder/IMemory.h> -#include <gui/ISurfaceComposer.h> - -#include <SkImageEncoder.h> -#include <SkBitmap.h> - -using namespace android; - -int main(int argc, char** argv) -{ - if (argc != 2) { - printf("usage: %s path\n", argv[0]); - exit(0); - } - - const String16 name("SurfaceFlinger"); - sp<ISurfaceComposer> composer; - getService(name, &composer); - - sp<IMemoryHeap> heap; - uint32_t w, h; - PixelFormat f; - status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0); - if (err != NO_ERROR) { - fprintf(stderr, "screen capture failed: %s\n", strerror(-err)); - exit(0); - } - - printf("screen capture success: w=%u, h=%u, pixels=%p\n", - w, h, heap->getBase()); - - printf("saving file as PNG in %s ...\n", argv[1]); - - SkBitmap b; - b.setConfig(SkBitmap::kARGB_8888_Config, w, h); - b.setPixels(heap->getBase()); - SkImageEncoder::EncodeFile(argv[1], b, - SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality); - - return 0; -} diff --git a/services/surfaceflinger/tests/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk deleted file mode 100644 index c59060e..0000000 --- a/services/surfaceflinger/tests/surface/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - surface.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libbinder \ - libui \ - libgui - -LOCAL_MODULE:= test-surface - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp deleted file mode 100644 index a8878f7..0000000 --- a/services/surfaceflinger/tests/surface/surface.cpp +++ /dev/null @@ -1,66 +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 <cutils/memory.h> - -#include <utils/Log.h> - -#include <binder/IPCThreadState.h> -#include <binder/ProcessState.h> -#include <binder/IServiceManager.h> - -#include <gui/Surface.h> -#include <gui/SurfaceComposerClient.h> - -using namespace android; - -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(); - - sp<SurfaceControl> surfaceControl = client->createSurface( - 0, 160, 240, PIXEL_FORMAT_RGB_565); - SurfaceComposerClient::openGlobalTransaction(); - surfaceControl->setLayer(100000); - SurfaceComposerClient::closeGlobalTransaction(); - - // pretend it went cross-process - Parcel parcel; - SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel); - parcel.setDataPosition(0); - sp<Surface> surface = Surface::readFromParcel(parcel); - ANativeWindow* window = surface.get(); - - printf("window=%p\n", window); - - int err = native_window_set_buffer_count(window, 8); - ANativeWindowBuffer* buffer; - - for (int i=0 ; i<8 ; i++) { - window->dequeueBuffer(window, &buffer); - printf("buffer %d: %p\n", i, buffer); - } - - printf("test complete. CTRL+C to finish.\n"); - - IPCThreadState::self()->joinThreadPool(); - return 0; -} diff --git a/services/surfaceflinger/tests/transform/Android.mk b/services/surfaceflinger/tests/transform/Android.mk deleted file mode 100644 index 6219dae..0000000 --- a/services/surfaceflinger/tests/transform/Android.mk +++ /dev/null @@ -1,19 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - TransformTest.cpp \ - ../../Transform.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libui \ - -LOCAL_MODULE:= test-transform - -LOCAL_MODULE_TAGS := tests - -LOCAL_C_INCLUDES += ../.. - -include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/transform/TransformTest.cpp b/services/surfaceflinger/tests/transform/TransformTest.cpp deleted file mode 100644 index e112c4e..0000000 --- a/services/surfaceflinger/tests/transform/TransformTest.cpp +++ /dev/null @@ -1,45 +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 <utils/Errors.h> -#include "../../Transform.h" - -using namespace android; - -int main(int argc, char **argv) -{ - Transform tr90(Transform::ROT_90); - Transform trFH(Transform::FLIP_H); - Transform trFV(Transform::FLIP_V); - - Transform tr90FH(Transform::ROT_90 | Transform::FLIP_H); - Transform tr90FV(Transform::ROT_90 | Transform::FLIP_V); - - tr90.dump("tr90"); - trFH.dump("trFH"); - trFV.dump("trFV"); - - tr90FH.dump("tr90FH"); - tr90FV.dump("tr90FV"); - - (trFH*tr90).dump("trFH*tr90"); - (trFV*tr90).dump("trFV*tr90"); - - (tr90*trFH).dump("tr90*trFH"); - (tr90*trFV).dump("tr90*trFV"); - - return 0; -} diff --git a/services/surfaceflinger/tests/vsync/Android.mk b/services/surfaceflinger/tests/vsync/Android.mk deleted file mode 100644 index 9181760..0000000 --- a/services/surfaceflinger/tests/vsync/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - vsync.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libbinder \ - libui \ - libgui - -LOCAL_MODULE:= test-vsync-events - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp deleted file mode 100644 index b0d54c4..0000000 --- a/services/surfaceflinger/tests/vsync/vsync.cpp +++ /dev/null @@ -1,83 +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 <gui/DisplayEventReceiver.h> -#include <utils/Looper.h> - -using namespace android; - -int receiver(int fd, int events, void* data) -{ - DisplayEventReceiver* q = (DisplayEventReceiver*)data; - - ssize_t n; - DisplayEventReceiver::Event buffer[1]; - - static nsecs_t oldTimeStamp = 0; - - while ((n = q->getEvents(buffer, 1)) > 0) { - for (int i=0 ; i<n ; i++) { - if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { - printf("event vsync: count=%d\t", buffer[i].vsync.count); - } - if (oldTimeStamp) { - float t = float(buffer[i].header.timestamp - oldTimeStamp) / s2ns(1); - printf("%f ms (%f Hz)\n", t*1000, 1.0/t); - } - oldTimeStamp = buffer[i].header.timestamp; - } - } - if (n<0) { - printf("error reading events (%s)\n", strerror(-n)); - } - return 1; -} - -int main(int argc, char** argv) -{ - DisplayEventReceiver myDisplayEvent; - - - sp<Looper> loop = new Looper(false); - loop->addFd(myDisplayEvent.getFd(), 0, ALOOPER_EVENT_INPUT, receiver, - &myDisplayEvent); - - myDisplayEvent.setVsyncRate(1); - - do { - //printf("about to poll...\n"); - int32_t ret = loop->pollOnce(-1); - switch (ret) { - case ALOOPER_POLL_WAKE: - //("ALOOPER_POLL_WAKE\n"); - break; - case ALOOPER_POLL_CALLBACK: - //("ALOOPER_POLL_CALLBACK\n"); - break; - case ALOOPER_POLL_TIMEOUT: - printf("ALOOPER_POLL_TIMEOUT\n"); - break; - case ALOOPER_POLL_ERROR: - printf("ALOOPER_POLL_TIMEOUT\n"); - break; - default: - printf("ugh? poll returned %d\n", ret); - break; - } - } while (1); - - return 0; -} diff --git a/services/surfaceflinger/tests/waitforvsync/Android.mk b/services/surfaceflinger/tests/waitforvsync/Android.mk deleted file mode 100644 index c25f5ab..0000000 --- a/services/surfaceflinger/tests/waitforvsync/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - waitforvsync.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - -LOCAL_MODULE:= test-waitforvsync - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp deleted file mode 100644 index 279b88b..0000000 --- a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2011 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 <sys/types.h> - -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/fb.h> -#include <errno.h> -#include <string.h> -#include <stdio.h> - -#ifndef FBIO_WAITFORVSYNC -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -#endif - -int main(int argc, char** argv) { - int fd = open("/dev/graphics/fb0", O_RDWR); - if (fd >= 0) { - do { - uint32_t crt = 0; - int err = ioctl(fd, FBIO_WAITFORVSYNC, &crt); - if (err < 0) { - printf("FBIO_WAITFORVSYNC error: %s\n", strerror(errno)); - break; - } - } while(1); - close(fd); - } - return 0; -} |