diff options
Diffstat (limited to 'services/surfaceflinger')
27 files changed, 307 insertions, 168 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index eade2e2..1eb2361 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -1,10 +1,10 @@ -LOCAL_PATH:= $(call my-dir) +LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk -LOCAL_SRC_FILES:= \ +LOCAL_SRC_FILES := \ Client.cpp \ DisplayDevice.cpp \ DispSync.cpp \ @@ -37,18 +37,18 @@ LOCAL_SRC_FILES:= \ RenderEngine/GLES20RenderEngine.cpp -LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" +LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_BOARD_PLATFORM),omap4) - LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY + LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY endif ifeq ($(TARGET_BOARD_PLATFORM),s5pc110) - LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY + LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY endif ifeq ($(TARGET_DISABLE_TRIPLE_BUFFERING),true) - LOCAL_CFLAGS += -DTARGET_DISABLE_TRIPLE_BUFFERING + LOCAL_CFLAGS += -DTARGET_DISABLE_TRIPLE_BUFFERING endif ifeq ($(TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS),true) @@ -56,7 +56,7 @@ ifeq ($(TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS),true) endif ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),) - LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) + LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) endif ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true) @@ -93,20 +93,22 @@ LOCAL_CFLAGS += -fvisibility=hidden -Werror=format LOCAL_CFLAGS += -std=c++11 LOCAL_SHARED_LIBRARIES := \ - libcutils \ - liblog \ - libdl \ - libhardware \ - libutils \ - libEGL \ - libGLESv1_CM \ - libGLESv2 \ - libbinder \ - libui \ - libgui \ - libpowermanager - -LOCAL_MODULE:= libsurfaceflinger + libcutils \ + liblog \ + libdl \ + libhardware \ + libutils \ + libEGL \ + libGLESv1_CM \ + libGLESv2 \ + libbinder \ + libui \ + libgui \ + libpowermanager + +LOCAL_MODULE := libsurfaceflinger + +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_SHARED_LIBRARY) @@ -114,46 +116,56 @@ include $(BUILD_SHARED_LIBRARY) # build surfaceflinger's executable include $(CLEAR_VARS) +LOCAL_CLANG := true + LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic -LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" -LOCAL_CPPFLAGS:= -std=c++11 +LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" +LOCAL_CPPFLAGS := -std=c++11 -LOCAL_SRC_FILES:= \ - main_surfaceflinger.cpp +LOCAL_SRC_FILES := \ + main_surfaceflinger.cpp LOCAL_SHARED_LIBRARIES := \ - libsurfaceflinger \ - libcutils \ - liblog \ - libbinder \ - libutils \ - libdl + libsurfaceflinger \ + libcutils \ + liblog \ + libbinder \ + libutils \ + libdl LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain -LOCAL_MODULE:= surfaceflinger +LOCAL_MODULE := surfaceflinger ifdef TARGET_32_BIT_SURFACEFLINGER LOCAL_32_BIT_ONLY := true endif +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code + include $(BUILD_EXECUTABLE) ############################################################### # uses jni which may not be available in PDK ifneq ($(wildcard libnativehelper/include),) include $(CLEAR_VARS) -LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" -LOCAL_SRC_FILES:= \ +LOCAL_CLANG := true + +LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" +LOCAL_CPPFLAGS := -std=c++11 + +LOCAL_SRC_FILES := \ DdmConnection.cpp LOCAL_SHARED_LIBRARIES := \ - libcutils \ - liblog \ - libdl + libcutils \ + liblog \ + libdl + +LOCAL_MODULE := libsurfaceflinger_ddmconnection -LOCAL_MODULE:= libsurfaceflinger_ddmconnection +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_SHARED_LIBRARY) endif # libnativehelper diff --git a/services/surfaceflinger/DdmConnection.cpp b/services/surfaceflinger/DdmConnection.cpp index 2477921..a000a84 100644 --- a/services/surfaceflinger/DdmConnection.cpp +++ b/services/surfaceflinger/DdmConnection.cpp @@ -59,12 +59,14 @@ void DdmConnection::start(const char* name) { } jint (*JNI_CreateJavaVM)(JavaVM** p_vm, JNIEnv** p_env, void* vm_args); - JNI_CreateJavaVM = (typeof JNI_CreateJavaVM)dlsym(libart_dso, "JNI_CreateJavaVM"); + JNI_CreateJavaVM = reinterpret_cast<decltype(JNI_CreateJavaVM)>( + dlsym(libart_dso, "JNI_CreateJavaVM")); ALOGE_IF(!JNI_CreateJavaVM, "DdmConnection: %s", dlerror()); jint (*registerNatives)(JNIEnv* env, jclass clazz); - registerNatives = (typeof registerNatives)dlsym(libandroid_runtime_dso, - "Java_com_android_internal_util_WithFramework_registerNatives"); + registerNatives = reinterpret_cast<decltype(registerNatives)>( + dlsym(libandroid_runtime_dso, + "Java_com_android_internal_util_WithFramework_registerNatives")); ALOGE_IF(!registerNatives, "DdmConnection: %s", dlerror()); if (!JNI_CreateJavaVM || !registerNatives) { diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 564f974..13d44f3 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -44,6 +44,18 @@ using namespace android; // ---------------------------------------------------------------------------- +#ifdef EGL_ANDROID_swap_rectangle +static constexpr bool kEGLAndroidSwapRectangle = true; +#else +static constexpr bool kEGLAndroidSwapRectangle = false; +#endif + +#if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle) +// Dummy implementation in case it is missing. +inline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) { +} +#endif + /* * Initialize the display to the specified values. * @@ -84,7 +96,6 @@ DisplayDevice::DisplayDevice( */ EGLSurface surface; - EGLint w, h; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (config == EGL_NO_CONFIG) { config = RenderEngine::chooseEglConfig(display, format); @@ -188,19 +199,14 @@ void DisplayDevice::flip(const Region& dirty) const { mFlinger->getRenderEngine().checkErrors(); - 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()); + if (kEGLAndroidSwapRectangle) { + if (mFlags & SWAP_RECTANGLE) { + const Region newDirty(dirty.intersect(bounds())); + const Rect b(newDirty.getBounds()); + eglSetSwapRectangleANDROID(mDisplay, mSurface, + b.left, b.top, b.width(), b.height()); + } } -#else - (void) dirty; // Eliminate unused parameter warning -#endif mPageFlipCount++; } @@ -511,6 +517,6 @@ void DisplayDevice::dump(String8& result) const { tr[0][2], tr[1][2], tr[2][2]); String8 surfaceDump; - mDisplaySurface->dump(surfaceDump); + mDisplaySurface->dumpAsString(surfaceDump); result.append(surfaceDump); } diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h index e60c4fb..2f743c1 100644 --- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h @@ -70,7 +70,7 @@ public: // frame's buffer. virtual void onFrameCommitted() = 0; - virtual void dump(String8& result) const = 0; + virtual void dumpAsString(String8& result) const = 0; virtual void resizeBuffers(const uint32_t w, const uint32_t h) = 0; diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index 22d3cec..6ef3295 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -29,8 +29,9 @@ #include <EGL/egl.h> #include <hardware/hardware.h> -#include <gui/Surface.h> +#include <gui/BufferItem.h> #include <gui/GraphicBufferAlloc.h> +#include <gui/Surface.h> #include <ui/GraphicBuffer.h> #include "FramebufferSurface.h" @@ -86,7 +87,7 @@ status_t FramebufferSurface::advanceFrame() { status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { Mutex::Autolock lock(mMutex); - BufferQueue::BufferItem item; + BufferItem item; status_t err = acquireBufferLocked(&item, 0); if (err == BufferQueue::NO_BUFFER_AVAILABLE) { outBuffer = mCurrentBuffer; @@ -160,23 +161,7 @@ status_t FramebufferSurface::compositionComplete() return mHwc.fbCompositionComplete(); } -// Since DisplaySurface and ConsumerBase both have a method with this -// signature, results will vary based on the static pointer type the caller is -// using: -// void dump(FrameBufferSurface* fbs, String8& s) { -// // calls FramebufferSurface::dump() -// fbs->dump(s); -// -// // calls ConsumerBase::dump() since it is non-virtual -// static_cast<ConsumerBase*>(fbs)->dump(s); -// -// // calls FramebufferSurface::dump() since it is virtual -// static_cast<DisplaySurface*>(fbs)->dump(s); -// } -// To make sure that all of these end up doing the same thing, we just redirect -// to ConsumerBase::dump() here. It will take the internal lock, and then call -// virtual dumpLocked(), which is where the real work happens. -void FramebufferSurface::dump(String8& result) const { +void FramebufferSurface::dumpAsString(String8& result) const { ConsumerBase::dump(result); } diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index 8605862..3d17840 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -44,10 +44,7 @@ public: virtual status_t compositionComplete(); virtual status_t advanceFrame(); virtual void onFrameCommitted(); - - // Implementation of DisplaySurface::dump(). Note that ConsumerBase also - // has a non-virtual dump() with the same signature. - virtual void dump(String8& result) const; + virtual void dumpAsString(String8& result) const; // Cannot resize a buffers in a FramebufferSurface. Only works with virtual // displays. diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index edfed49..c8b36ec 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -1020,6 +1020,21 @@ public: SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects); visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); } + virtual void setSurfaceDamage(const Region& reg) { + if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) { + return; + } + hwc_region_t& surfaceDamage = getLayer()->surfaceDamage; + // We encode default full-screen damage as INVALID_RECT upstream, but as + // 0 rects for HWComposer + if (reg.isRect() && reg.getBounds() == Rect::INVALID_RECT) { + surfaceDamage.numRects = 0; + surfaceDamage.rects = NULL; + return; + } + SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects); + surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); + } virtual void setSidebandStream(const sp<NativeHandle>& stream) { ALOG_ASSERT(stream->handle() != NULL); getLayer()->compositionType = HWC_SIDEBAND; @@ -1050,6 +1065,18 @@ public: } getLayer()->acquireFenceFd = -1; + + if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) { + return; + } + + hwc_region_t& surfaceDamage = getLayer()->surfaceDamage; + sb = SharedBuffer::bufferFromData(surfaceDamage.rects); + if (sb) { + sb->release(); + surfaceDamage.numRects = 0; + surfaceDamage.rects = NULL; + } } }; @@ -1105,8 +1132,6 @@ static String8 getFormatStr(PixelFormat format) { case PIXEL_FORMAT_RGB_888: return String8("RGB_888"); case PIXEL_FORMAT_RGB_565: return String8("RGB_565"); case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888"); - case PIXEL_FORMAT_sRGB_A_8888: return String8("sRGB_A_8888"); - case PIXEL_FORMAT_sRGB_X_8888: return String8("sRGB_x_8888"); case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return String8("ImplDef"); default: diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index a62ac5c..28d8c65 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -168,6 +168,7 @@ public: virtual void setFrame(const Rect& frame) = 0; virtual void setCrop(const FloatRect& crop) = 0; virtual void setVisibleRegionScreen(const Region& reg) = 0; + virtual void setSurfaceDamage(const Region& reg) = 0; virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0; virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0; virtual void setAcquireFenceFd(int fenceFd) = 0; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c3d45ee..11cbdc6 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -18,6 +18,8 @@ #include "VirtualDisplaySurface.h" #include "HWComposer.h" +#include <gui/BufferItem.h> + // --------------------------------------------------------------------------- namespace android { // --------------------------------------------------------------------------- @@ -234,6 +236,7 @@ void VirtualDisplaySurface::onFrameCommitted() { status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, QueueBufferInput( systemTime(), false /* isAutoTimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mSinkBufferWidth, mSinkBufferHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */, true /* async*/, @@ -254,7 +257,7 @@ void VirtualDisplaySurface::onFrameCommitted() { resetPerFrameState(); } -void VirtualDisplaySurface::dump(String8& /* result */) const { +void VirtualDisplaySurface::dumpAsString(String8& /* result */) const { } void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) { @@ -284,7 +287,7 @@ status_t VirtualDisplaySurface::setBufferCount(int bufferCount) { } status_t VirtualDisplaySurface::dequeueBuffer(Source source, - uint32_t format, uint32_t usage, int* sslot, sp<Fence>* fence) { + PixelFormat format, uint32_t usage, int* sslot, sp<Fence>* fence) { LOG_FATAL_IF(mDisplayId < 0, "mDisplayId=%d but should not be < 0.", mDisplayId); // Don't let a slow consumer block us bool async = (source == SOURCE_SINK); @@ -329,7 +332,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source, } status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool async, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { + uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) { if (mDisplayId < 0) return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, async, w, h, format, usage); @@ -364,7 +367,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool usage |= GRALLOC_USAGE_HW_COMPOSER; const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot]; if ((usage & ~buf->getUsage()) != 0 || - (format != 0 && format != (uint32_t)buf->getPixelFormat()) || + (format != 0 && format != buf->getPixelFormat()) || (w != 0 && w != mSinkBufferWidth) || (h != 0 && h != mSinkBufferHeight)) { VDS_LOGV("dequeueBuffer: dequeueing new output buffer: " @@ -435,7 +438,7 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, // Now acquire the buffer from the scratch pool -- should be the same // slot and fence as we just queued. Mutex::Autolock lock(mMutex); - BufferQueue::BufferItem item; + BufferItem item; result = acquireBufferLocked(&item, 0); if (result != NO_ERROR) return result; @@ -453,12 +456,13 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, // Extract the GLES release fence for HWC to acquire int64_t timestamp; bool isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; bool async; - input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, - &transform, &async, &mFbFence); + input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, + &scalingMode, &transform, &async, &mFbFence); mFbProducerSlot = pslot; mOutputFence = mFbFence; @@ -517,11 +521,15 @@ status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stre } void VirtualDisplaySurface::allocateBuffers(bool /* async */, - uint32_t /* width */, uint32_t /* height */, uint32_t /* format */, + uint32_t /* width */, uint32_t /* height */, PixelFormat /* format */, uint32_t /* usage */) { // TODO: Should we actually allocate buffers for a virtual display? } +status_t VirtualDisplaySurface::allowAllocation(bool /* allow */) { + return INVALID_OPERATION; +} + void VirtualDisplaySurface::updateQueueBufferOutput( const QueueBufferOutput& qbo) { uint32_t w, h, transformHint, numPendingBuffers; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 363dce2..97af980 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -86,7 +86,7 @@ public: virtual status_t compositionComplete(); virtual status_t advanceFrame(); virtual void onFrameCommitted(); - virtual void dump(String8& result) const; + virtual void dumpAsString(String8& result) const; virtual void resizeBuffers(const uint32_t w, const uint32_t h); private: @@ -100,7 +100,7 @@ private: virtual status_t requestBuffer(int pslot, sp<GraphicBuffer>* outBuf); virtual status_t setBufferCount(int bufferCount); virtual status_t dequeueBuffer(int* pslot, sp<Fence>* fence, bool async, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage); + uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); virtual status_t detachBuffer(int slot); virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence); @@ -114,13 +114,14 @@ private: virtual status_t disconnect(int api); virtual status_t setSidebandStream(const sp<NativeHandle>& stream); virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, - uint32_t format, uint32_t usage); + PixelFormat format, uint32_t usage); + virtual status_t allowAllocation(bool allow); // // Utility methods // static Source fbSourceForCompositionType(CompositionType type); - status_t dequeueBuffer(Source source, uint32_t format, uint32_t usage, + status_t dequeueBuffer(Source source, PixelFormat format, uint32_t usage, int* sslot, sp<Fence>* fence); void updateQueueBufferOutput(const QueueBufferOutput& qbo); void resetPerFrameState(); diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 9b6360e..f760200 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -71,6 +71,11 @@ void EventThread::sendVsyncHintOff() { mVsyncHintSent = false; } +void EventThread::setPhaseOffset(nsecs_t phaseOffset) { + Mutex::Autolock _l(mLock); + mVSyncSource->setPhaseOffset(phaseOffset); +} + void EventThread::sendVsyncHintOnLocked() { struct itimerspec ts; if(!mVsyncHintSent) { diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h index d1c4fcd..9ba179a 100644 --- a/services/surfaceflinger/EventThread.h +++ b/services/surfaceflinger/EventThread.h @@ -51,6 +51,7 @@ public: virtual ~VSyncSource() {} virtual void setVSyncEnabled(bool enable) = 0; virtual void setCallback(const sp<Callback>& callback) = 0; + virtual void setPhaseOffset(nsecs_t phaseOffset) = 0; }; class EventThread : public Thread, private VSyncSource::Callback { @@ -99,6 +100,8 @@ public: void dump(String8& result) const; void sendVsyncHintOff(); + void setPhaseOffset(nsecs_t phaseOffset); + private: virtual bool threadLoop(); virtual void onFirstRef(); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5e3dfab..2944c63 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -64,7 +64,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mTextureName(-1U), mPremultipliedAlpha(true), mName("unnamed"), - mDebug(false), mFormat(PIXEL_FORMAT_NONE), mTransactionFlags(0), mQueuedFrames(0), @@ -514,6 +513,16 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); layer.setVisibleRegionScreen(visible); + // Pass full-surface damage down untouched + if (surfaceDamageRegion.isRect() && + surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) { + layer.setSurfaceDamage(surfaceDamageRegion); + } else { + Region surfaceDamage = + tr.transform(surfaceDamageRegion.intersect(hw->getViewport())); + layer.setSurfaceDamage(surfaceDamage); + } + if (mSidebandStream.get()) { layer.setSidebandStream(mSidebandStream); } else { @@ -693,7 +702,6 @@ void Layer::clearWithOpenGL( void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& /* clip */, bool useIdentityTransform) const { - const uint32_t fbHeight = hw->getHeight(); const State& s(getDrawingState()); computeGeometry(hw, mMesh, useIdentityTransform); @@ -766,7 +774,6 @@ bool Layer::getOpacityForFormat(uint32_t format) { switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: return false; } // in all other case, we have no blending (also for unknown formats) @@ -911,7 +918,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { const bool resizePending = (c.requested.w != c.active.w) || (c.requested.h != c.active.h); - if (resizePending) { + if (resizePending && mSidebandStream == NULL) { // don't let Layer::doTransaction update the drawing state // if we have a pending resize, unless we are in fixed-size mode. // the drawing state will be updated only once we receive a buffer @@ -920,6 +927,10 @@ uint32_t Layer::doTransaction(uint32_t flags) { // in particular, we want to make sure the clip (which is part // of the geometry state) is latched together with the size but is // latched immediately when no resizing is involved. + // + // If a sideband stream is attached, however, we want to skip this + // optimization so that transactions aren't missed when a buffer + // never arrives flags |= eDontUpdateGeometryState; } @@ -1037,6 +1048,18 @@ bool Layer::setLayerStack(uint32_t layerStack) { return true; } +void Layer::useSurfaceDamage() { + if (mFlinger->mForceFullDamage) { + surfaceDamageRegion = Region::INVALID_REGION; + } else { + surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); + } +} + +void Layer::useEmptyDamage() { + surfaceDamageRegion.clear(); +} + // ---------------------------------------------------------------------------- // pageflip handling... // ---------------------------------------------------------------------------- @@ -1133,7 +1156,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) } virtual bool reject(const sp<GraphicBuffer>& buf, - const IGraphicBufferConsumer::BufferItem& item) { + const BufferItem& item) { if (buf == NULL) { return false; } @@ -1352,6 +1375,7 @@ void Layer::dump(String8& result, Colorizer& colorizer) const s.activeTransparentRegion.dump(result, "transparentRegion"); visibleRegion.dump(result, "visibleRegion"); + surfaceDamageRegion.dump(result, "surfaceDamageRegion"); sp<Client> client(mClientRef.promote()); result.appendFormat( " " diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 1d4eee7..46c17e5 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -76,6 +76,7 @@ public: Region visibleRegion; Region coveredRegion; Region visibleNonTransparentRegion; + Region surfaceDamageRegion; // Layer serial number. This gives layers an explicit ordering, so we // have a stable sort order when their layer stack and Z-order are @@ -137,6 +138,12 @@ public: bool setCrop(const Rect& crop); bool setLayerStack(uint32_t layerStack); + // If we have received a new buffer this frame, we will pass its surface + // damage down to hardware composer. Otherwise, we must send a region with + // one empty rect. + void useSurfaceDamage(); + void useEmptyDamage(); + uint32_t getTransactionFlags(uint32_t flags); uint32_t setTransactionFlags(uint32_t flags); @@ -364,7 +371,6 @@ private: uint32_t mTextureName; // from GLES bool mPremultipliedAlpha; String8 mName; - mutable bool mDebug; PixelFormat mFormat; // these are protected by an external lock diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp index 8739682..9fb555b 100644 --- a/services/surfaceflinger/MonitoredProducer.cpp +++ b/services/surfaceflinger/MonitoredProducer.cpp @@ -49,7 +49,7 @@ MonitoredProducer::~MonitoredProducer() { wp<IBinder> mProducer; }; - mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder())); + mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder(this))); } status_t MonitoredProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { @@ -61,7 +61,7 @@ status_t MonitoredProducer::setBufferCount(int bufferCount) { } status_t MonitoredProducer::dequeueBuffer(int* slot, sp<Fence>* fence, - bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { + bool async, uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) { return mProducer->dequeueBuffer(slot, fence, async, w, h, format, usage); } @@ -106,12 +106,16 @@ status_t MonitoredProducer::setSidebandStream(const sp<NativeHandle>& stream) { } void MonitoredProducer::allocateBuffers(bool async, uint32_t width, - uint32_t height, uint32_t format, uint32_t usage) { + uint32_t height, PixelFormat format, uint32_t usage) { mProducer->allocateBuffers(async, width, height, format, usage); } +status_t MonitoredProducer::allowAllocation(bool allow) { + return mProducer->allowAllocation(allow); +} + IBinder* MonitoredProducer::onAsBinder() { - return mProducer->asBinder().get(); + return IInterface::asBinder(mProducer).get(); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h index f6ccc51..b2f8293 100644 --- a/services/surfaceflinger/MonitoredProducer.h +++ b/services/surfaceflinger/MonitoredProducer.h @@ -37,7 +37,7 @@ public: virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); virtual status_t setBufferCount(int bufferCount); virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, bool async, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage); + uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); virtual status_t detachBuffer(int slot); virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence); @@ -52,7 +52,8 @@ public: virtual status_t disconnect(int api); virtual status_t setSidebandStream(const sp<NativeHandle>& stream); virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, - uint32_t format, uint32_t usage); + PixelFormat format, uint32_t usage); + virtual status_t allowAllocation(bool allow); virtual IBinder* onAsBinder(); private: diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index c2768f3..2e6af49 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -43,12 +43,6 @@ GLES11RenderEngine::GLES11RenderEngine() { glDisable(GL_DITHER); glDisable(GL_CULL_FACE); - struct pack565 { - inline uint16_t operator() (int r, int g, int b) const { - return (r<<11)|(g<<5)|b; - } - } pack565; - const uint16_t protTexData[] = { 0 }; glGenTextures(1, &mProtectedTexName); glBindTexture(GL_TEXTURE_2D, mProtectedTexName); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 8ebafbc..8712c9a 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -48,12 +48,6 @@ GLES20RenderEngine::GLES20RenderEngine() : glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4); - struct pack565 { - inline uint16_t operator() (int r, int g, int b) const { - return (r<<11)|(g<<5)|b; - } - } pack565; - const uint16_t protTexData[] = { 0 }; glGenTextures(1, &mProtectedTexName); glBindTexture(GL_TEXTURE_2D, mProtectedTexName); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index a77e0e9..7cd42e4 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -283,7 +283,6 @@ status_t RenderEngine::BindImageAsFramebuffer::getStatus() const { static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute, EGLint wanted, EGLConfig* outConfig) { - EGLConfig config = NULL; EGLint numConfigs = -1, n = 0; eglGetConfigs(dpy, NULL, 0, &numConfigs); EGLConfig* const configs = new EGLConfig[numConfigs]; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 80d3cc2..df4ac2e 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -145,6 +145,7 @@ SurfaceFlinger::SurfaceFlinger() mDebugInTransaction(0), mLastTransactionTime(0), mBootFinished(false), + mForceFullDamage(false), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), mDaltonize(false), @@ -319,17 +320,20 @@ public: DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, const char* label) : mValue(0), - mPhaseOffset(phaseOffset), mTraceVsync(traceVsync), mVsyncOnLabel(String8::format("VsyncOn-%s", label)), mVsyncEventLabel(String8::format("VSYNC-%s", label)), - mDispSync(dispSync) {} + mDispSync(dispSync), + mCallbackMutex(), + mCallback(), + mVsyncMutex(), + mPhaseOffset(phaseOffset), + mEnabled(false) {} virtual ~DispSyncSource() {} virtual void setVSyncEnabled(bool enable) { - // Do NOT lock the mutex here so as to avoid any mutex ordering issues - // with locking it in the onDispSyncEvent callback. + Mutex::Autolock lock(mVsyncMutex); if (enable) { status_t err = mDispSync->addEventListener(mPhaseOffset, static_cast<DispSync::Callback*>(this)); @@ -347,18 +351,54 @@ public: } //ATRACE_INT(mVsyncOnLabel.string(), 0); } + mEnabled = enable; } virtual void setCallback(const sp<VSyncSource::Callback>& callback) { - Mutex::Autolock lock(mMutex); + Mutex::Autolock lock(mCallbackMutex); mCallback = callback; } + virtual void setPhaseOffset(nsecs_t phaseOffset) { + Mutex::Autolock lock(mVsyncMutex); + + // Normalize phaseOffset to [0, period) + auto period = mDispSync->getPeriod(); + phaseOffset %= period; + if (phaseOffset < 0) { + // If we're here, then phaseOffset is in (-period, 0). After this + // operation, it will be in (0, period) + phaseOffset += period; + } + mPhaseOffset = phaseOffset; + + // If we're not enabled, we don't need to mess with the listeners + if (!mEnabled) { + return; + } + + // Remove the listener with the old offset + status_t err = mDispSync->removeEventListener( + static_cast<DispSync::Callback*>(this)); + if (err != NO_ERROR) { + ALOGE("error unregistering vsync callback: %s (%d)", + strerror(-err), err); + } + + // Add a listener with the new offset + err = mDispSync->addEventListener(mPhaseOffset, + static_cast<DispSync::Callback*>(this)); + if (err != NO_ERROR) { + ALOGE("error registering vsync callback: %s (%d)", + strerror(-err), err); + } + } + private: virtual void onDispSyncEvent(nsecs_t when) { sp<VSyncSource::Callback> callback; { - Mutex::Autolock lock(mMutex); + Mutex::Autolock lock(mCallbackMutex); callback = mCallback; if (mTraceVsync) { @@ -374,21 +414,24 @@ private: int mValue; - const nsecs_t mPhaseOffset; const bool mTraceVsync; const String8 mVsyncOnLabel; const String8 mVsyncEventLabel; DispSync* mDispSync; + + Mutex mCallbackMutex; // Protects the following sp<VSyncSource::Callback> mCallback; - Mutex mMutex; + + Mutex mVsyncMutex; // Protects the following + nsecs_t mPhaseOffset; + bool mEnabled; }; void SurfaceFlinger::init() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); - status_t err; Mutex::Autolock _l(mStateLock); // initialize EGL for the default display @@ -497,7 +540,7 @@ size_t SurfaceFlinger::getMaxViewportDims() const { bool SurfaceFlinger::authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) const { Mutex::Autolock _l(mStateLock); - sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder()); + sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; } @@ -607,7 +650,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, return NO_ERROR; } -status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& display, +status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, DisplayStatInfo* stats) { if (stats == NULL) { return BAD_VALUE; @@ -621,7 +664,11 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& display, } int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { - return getDisplayDevice(display)->getActiveConfig(); + sp<DisplayDevice> device(getDisplayDevice(display)); + if (device != NULL) { + return device->getActiveConfig(); + } + return BAD_VALUE; } void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { @@ -1288,7 +1335,9 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // this display is in both lists. see if something changed. const DisplayDeviceState& state(curr[j]); const wp<IBinder>& display(curr.keyAt(j)); - if (state.surface->asBinder() != draw[i].surface->asBinder()) { + const sp<IBinder> state_binder = IInterface::asBinder(state.surface); + const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); + if (state_binder != draw_binder) { // changing the surface is like destroying and // recreating the DisplayDevice, so we just remove it // from the drawing state, so that it get re-added @@ -1720,12 +1769,17 @@ bool SurfaceFlinger::handlePageFlip() frameQueued = true; if (layer->shouldPresentNow(mPrimaryDispSync)) { layersWithQueuedFrames.push_back(layer.get()); + } else { + layer->useEmptyDamage(); } + } else { + layer->useEmptyDamage(); } } for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { Layer* layer = layersWithQueuedFrames[i]; const Region dirty(layer->latchBuffer(visibleRegions)); + layer->useSurfaceDamage(); const Layer::State& s(layer->getDrawingState()); invalidateLayerStack(s.layerStack, dirty); } @@ -1951,7 +2005,7 @@ void SurfaceFlinger::addClientLayer(const sp<Client>& client, // add this layer to the current state list Mutex::Autolock _l(mStateLock); mCurrentState.layersSortedByZ.add(lbc); - mGraphicBufferProducerList.add(gbc->asBinder()); + mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); } status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { @@ -2024,7 +2078,7 @@ void SurfaceFlinger::setTransactionState( // NOTE: it would be better to use RTTI as we could directly check // that we have a Client*. however, RTTI is disabled in Android. if (s.client != NULL) { - sp<IBinder> binder = s.client->asBinder(); + sp<IBinder> binder = IInterface::asBinder(s.client); if (binder != NULL) { String16 desc(binder->getInterfaceDescriptor()); if (desc == ISurfaceComposerClient::descriptor) { @@ -2071,7 +2125,7 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) if (disp.isValid()) { const uint32_t what = s.what; if (what & DisplayState::eSurfaceChanged) { - if (disp.surface->asBinder() != s.surface->asBinder()) { + if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { disp.surface = s.surface; flags |= eDisplayTransactionNeeded; } @@ -2402,18 +2456,15 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) result.appendFormat("Permission Denial: " "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); } else { - // Try to get the main lock, but don't insist if we can't + // Try to get the main lock, but give up after one second // (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); + status_t err = mStateLock.timedLock(s2ns(1)); + bool locked = (err == NO_ERROR); if (!locked) { - result.append( - "SurfaceFlinger appears to be unresponsive, " - "dumping anyways (no locks held)\n"); + result.appendFormat( + "SurfaceFlinger appears to be unresponsive (%s [%d]), " + "dumping anyways (no locks held)\n", strerror(-err), err); } bool dumpAll = true; @@ -2874,6 +2925,21 @@ status_t SurfaceFlinger::onTransact( mPrimaryDispSync.setRefreshSkipCount(n); return NO_ERROR; } + case 1017: { + n = data.readInt32(); + mForceFullDamage = static_cast<bool>(n); + return NO_ERROR; + } + case 1018: { // Modify Choreographer's phase offset + n = data.readInt32(); + mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); + return NO_ERROR; + } + case 1019: { // Modify SurfaceFlinger's phase offset + n = data.readInt32(); + mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); + return NO_ERROR; + } } } return err; @@ -2962,7 +3028,7 @@ class GraphicProducerWrapper : public BBinder, public MessageHandler { // Prevent reads below from happening before the read from Message atomic_thread_fence(memory_order_acquire); if (what == MSG_API_CALL) { - result = impl->asBinder()->transact(code, data[0], reply); + result = IInterface::asBinder(impl)->transact(code, data[0], reply); barrier.open(); } else if (what == MSG_EXIT) { exitRequested = true; @@ -3012,7 +3078,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, // if we have secure windows on this display, never allow the screen capture // unless the producer interface is local (i.e.: we can take a screenshot for // ourselves). - if (!producer->asBinder()->localBinder()) { + if (!IInterface::asBinder(producer)->localBinder()) { Mutex::Autolock _l(mStateLock); sp<const DisplayDevice> hw(getDisplayDevice(display)); if (hw->getSecureLayerVisible()) { @@ -3076,7 +3142,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, result = flinger->captureScreenImplLocked(hw, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, rotation); - static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result); + static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); return true; } }; @@ -3118,9 +3184,10 @@ void SurfaceFlinger::renderScreenImplLocked( RenderEngine& engine(getRenderEngine()); // get screen geometry - const uint32_t hw_w = hw->getWidth(); - const uint32_t hw_h = hw->getHeight(); - const bool filtering = reqWidth != hw_w || reqWidth != hw_h; + const int32_t hw_w = hw->getWidth(); + const int32_t hw_h = hw->getHeight(); + const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || + static_cast<int32_t>(reqHeight) != hw_h; // if a default or invalid sourceCrop is passed in, set reasonable values if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || @@ -3133,13 +3200,13 @@ void SurfaceFlinger::renderScreenImplLocked( if (sourceCrop.left < 0) { ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); } - if (static_cast<uint32_t>(sourceCrop.right) > hw_w) { + if (sourceCrop.right > hw_w) { ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); } if (sourceCrop.top < 0) { ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); } - if (static_cast<uint32_t>(sourceCrop.bottom) > hw_h) { + if (sourceCrop.bottom > hw_h) { ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4deb815..a06d1be 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -469,6 +469,7 @@ private: volatile nsecs_t mDebugInTransaction; nsecs_t mLastTransactionTime; bool mBootFinished; + bool mForceFullDamage; // these are thread safe mutable MessageQueue mEventQueue; diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index 7de6ac4..19c497a 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -21,6 +21,8 @@ #include <private/gui/SyncFeatures.h> +#include <gui/BufferItem.h> + #include <utils/Errors.h> #include <utils/NativeHandle.h> #include <utils/Trace.h> @@ -47,7 +49,7 @@ status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter, return err; } - BufferQueue::BufferItem item; + BufferItem item; // Acquire the next buffer. // In asynchronous mode the list is guaranteed to be one buffer @@ -101,11 +103,12 @@ status_t SurfaceFlingerConsumer::bindTextureImage() return bindTextureImageLocked(); } -status_t SurfaceFlingerConsumer::acquireBufferLocked( - BufferQueue::BufferItem *item, nsecs_t presentWhen) { +status_t SurfaceFlingerConsumer::acquireBufferLocked(BufferItem* item, + nsecs_t presentWhen) { status_t result = GLConsumer::acquireBufferLocked(item, presentWhen); if (result == NO_ERROR) { mTransformToDisplayInverse = item->mTransformToDisplayInverse; + mSurfaceDamage = item->mSurfaceDamage; } return result; } @@ -114,6 +117,10 @@ bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const { return mTransformToDisplayInverse; } +const Region& SurfaceFlingerConsumer::getSurfaceDamage() const { + return mSurfaceDamage; +} + sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const { return mConsumer->getSidebandStream(); } diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index 28f2f6a..1aaba18 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -35,19 +35,19 @@ public: SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer, uint32_t tex) : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false), - mTransformToDisplayInverse(false) + mTransformToDisplayInverse(false), mSurfaceDamage() {} class BufferRejecter { friend class SurfaceFlingerConsumer; virtual bool reject(const sp<GraphicBuffer>& buf, - const IGraphicBufferConsumer::BufferItem& item) = 0; + const BufferItem& item) = 0; protected: virtual ~BufferRejecter() { } }; - virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item, nsecs_t presentWhen); + virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen); // This version of updateTexImage() takes a functor that may be used to // reject the newly acquired buffer. Unlike the GLConsumer version, @@ -60,6 +60,7 @@ public: // must be called from SF main thread bool getTransformToDisplayInverse() const; + const Region& getSurfaceDamage() const; // Sets the contents changed listener. This should be used instead of // ConsumerBase::setFrameAvailableListener(). @@ -78,6 +79,9 @@ private: // it is displayed onto. This is applied after GLConsumer::mCurrentTransform. // This must be set/read from SurfaceFlinger's main thread. bool mTransformToDisplayInverse; + + // The portion of this surface that has changed since the previous frame + Region mSurfaceDamage; }; // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index 90e3f7d..a74bc4c 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -14,9 +14,7 @@ * limitations under the License. */ -#if defined(HAVE_PTHREADS) #include <sys/resource.h> -#endif #include <cutils/sched_policy.h> #include <binder/IServiceManager.h> @@ -39,9 +37,8 @@ int main(int, char**) { // instantiate surfaceflinger sp<SurfaceFlinger> flinger = new SurfaceFlinger(); -#if defined(HAVE_PTHREADS) setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY); -#endif + set_sched_policy(0, SP_FOREGROUND); // initialize before clients can connect diff --git a/services/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk index e210860..979062e 100644 --- a/services/surfaceflinger/tests/Android.mk +++ b/services/surfaceflinger/tests/Android.mk @@ -1,6 +1,7 @@ # Build the unit tests, LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_MODULE := SurfaceFlinger_test @@ -15,16 +16,9 @@ LOCAL_SHARED_LIBRARIES := \ 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) diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp index b0d54c4..aa72c79 100644 --- a/services/surfaceflinger/tests/vsync/vsync.cpp +++ b/services/surfaceflinger/tests/vsync/vsync.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <android/looper.h> #include <gui/DisplayEventReceiver.h> #include <utils/Looper.h> diff --git a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp index 279b88b..b88b04a 100644 --- a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp +++ b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp @@ -23,6 +23,7 @@ #include <errno.h> #include <string.h> #include <stdio.h> +#include <unistd.h> #ifndef FBIO_WAITFORVSYNC #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) |