diff options
28 files changed, 362 insertions, 312 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 00bd54e..53c77da 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -16,6 +16,7 @@ ** limitations under the License. */ +//#define LOG_NDEBUG 0 #define LOG_TAG "CameraService" #include <utils/Log.h> @@ -247,7 +248,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, status_t CameraService::Client::checkPid() { int callingPid = getCallingPid(); - if (mClientPid == callingPid) return NO_ERROR; + if (mClientPid == callingPid || callingPid == getpid()) return NO_ERROR; LOGW("Attempt to use locked camera (client %p) from different process " " (old pid %d, new pid %d)", getCameraClient()->asBinder().get(), mClientPid, callingPid); diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h index 9b5a1e0..6ace5bc 100644 --- a/include/private/surfaceflinger/SharedBufferStack.h +++ b/include/private/surfaceflinger/SharedBufferStack.h @@ -58,7 +58,7 @@ namespace android { // When changing these values, the COMPILE_TIME_ASSERT at the end of this // file need to be updated. const unsigned int NUM_LAYERS_MAX = 31; -const unsigned int NUM_BUFFER_MAX = 4; +const unsigned int NUM_BUFFER_MAX = 16; const unsigned int NUM_DISPLAY_MAX = 4; // ---------------------------------------------------------------------------- @@ -69,7 +69,11 @@ class SharedClient; // ---------------------------------------------------------------------------- -// should be 128 bytes (32 longs) +// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX +// 4 * (11 + 7 + (1 + 2*7)*16) * 31 +// 1032 * 31 +// = ~27 KiB (31992) + class SharedBufferStack { friend class SharedClient; @@ -78,21 +82,31 @@ class SharedBufferStack friend class SharedBufferServer; public: - struct FlatRegion { // 12 bytes - static const unsigned int NUM_RECT_MAX = 1; - uint32_t count; - uint16_t rects[4*NUM_RECT_MAX]; - }; - struct Statistics { // 4 longs typedef int32_t usecs_t; usecs_t totalTime; usecs_t reserved[3]; }; + + struct SmallRect { + uint16_t l, t, r, b; + }; + + struct FlatRegion { // 52 bytes = 4 * (1 + 2*N) + static const unsigned int NUM_RECT_MAX = 6; + uint32_t count; + SmallRect rects[NUM_RECT_MAX]; + }; + + struct BufferData { + FlatRegion dirtyRegion; + SmallRect crop; + }; SharedBufferStack(); void init(int32_t identity); status_t setDirtyRegion(int buffer, const Region& reg); + status_t setCrop(int buffer, const Rect& reg); Region getDirtyRegion(int buffer) const; // these attributes are part of the conditions/updates @@ -106,9 +120,10 @@ public: volatile int32_t reallocMask; int32_t identity; // surface's identity (const) - int32_t reserved32[9]; + int32_t reserved32[6]; Statistics stats; - FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes + int32_t reserved; + BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes }; // ---------------------------------------------------------------------------- @@ -238,6 +253,7 @@ public: status_t queue(int buf); bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); + status_t setCrop(int buffer, const Rect& reg); private: friend struct Condition; @@ -349,8 +365,7 @@ struct surface_flinger_cblk_t // 4KB max // --------------------------------------------------------------------------- -COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096) -COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128) +COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768) COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096) // --------------------------------------------------------------------------- diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceFlingerClient.h index d257645..c96432f 100644 --- a/include/surfaceflinger/ISurfaceFlingerClient.h +++ b/include/surfaceflinger/ISurfaceFlingerClient.h @@ -59,6 +59,9 @@ public: virtual sp<IMemoryHeap> getControlBlock() const = 0; + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ virtual sp<ISurface> createSurface( surface_data_t* data, int pid, const String8& name, @@ -68,8 +71,14 @@ public: PixelFormat format, uint32_t flags) = 0; + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ virtual status_t destroySurface(SurfaceID sid) = 0; + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ virtual status_t setState(int32_t count, const layer_state_t* states) = 0; }; diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 0279d84..40dc467 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -30,6 +30,8 @@ #include <surfaceflinger/ISurface.h> #include <surfaceflinger/ISurfaceFlingerClient.h> +#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface" + namespace android { // --------------------------------------------------------------------------- @@ -213,10 +215,12 @@ private: void dispatch_setUsage(va_list args); int dispatch_connect(va_list args); int dispatch_disconnect(va_list args); + int dispatch_crop(va_list args); void setUsage(uint32_t reqUsage); int connect(int api); int disconnect(int api); + int crop(Rect const* rect); uint32_t getUsage() const; int getConnectedApi() const; @@ -235,6 +239,7 @@ private: Rect mSwapRectangle; uint32_t mUsage; int mConnected; + Rect mNextBufferCrop; // protected by mSurfaceLock. These are also used from lock/unlock // but in that case, they must be called form the same thread. @@ -245,7 +250,7 @@ private: sp<GraphicBuffer> mLockedBuffer; sp<GraphicBuffer> mPostedBuffer; mutable Region mOldDirtyRegion; - bool mNeedFullUpdate; + bool mReserved; // query() must be called from dequeueBuffer() thread uint32_t mWidth; diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h index 741d763..54b8236 100644 --- a/include/ui/GraphicBufferAllocator.h +++ b/include/ui/GraphicBufferAllocator.h @@ -73,9 +73,9 @@ private: struct alloc_rec_t { uint32_t w; uint32_t h; + uint32_t s; PixelFormat format; uint32_t usage; - void* vaddr; size_t size; }; diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index 773fd93..471c3c7 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -41,6 +41,14 @@ extern "C" { struct android_native_buffer_t; +typedef struct android_native_rect_t +{ + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} android_native_rect_t; + // --------------------------------------------------------------------------- typedef struct android_native_base_t @@ -63,15 +71,16 @@ typedef struct android_native_base_t /* attributes queriable with query() */ enum { NATIVE_WINDOW_WIDTH = 0, - NATIVE_WINDOW_HEIGHT = 1, - NATIVE_WINDOW_FORMAT = 2, + NATIVE_WINDOW_HEIGHT, + NATIVE_WINDOW_FORMAT, }; /* valid operations for the (*perform)() hook */ enum { NATIVE_WINDOW_SET_USAGE = 0, - NATIVE_WINDOW_CONNECT = 1, - NATIVE_WINDOW_DISCONNECT = 2 + NATIVE_WINDOW_CONNECT, + NATIVE_WINDOW_DISCONNECT, + NATIVE_WINDOW_SET_CROP, }; /* parameter for NATIVE_WINDOW_[DIS]CONNECT */ @@ -125,7 +134,7 @@ typedef struct android_native_window_t * * Returns 0 on success or -errno on error. */ - int (*dequeueBuffer)(struct android_native_window_t* window, + int (*dequeueBuffer)(struct android_native_window_t* window, struct android_native_buffer_t** buffer); /* @@ -171,6 +180,7 @@ typedef struct android_native_window_t * NATIVE_WINDOW_SET_USAGE * NATIVE_WINDOW_CONNECT * NATIVE_WINDOW_DISCONNECT + * NATIVE_WINDOW_SET_CROP * */ @@ -221,6 +231,24 @@ static inline int native_window_disconnect( return window->perform(window, NATIVE_WINDOW_DISCONNECT, api); } +/* + * native_window_set_crop(..., crop) sets which region of the next queued + * buffers needs to be considered. + * A buffer's crop region is scaled to match the surface's size. + * + * The specified crop region applies to all buffers queued after it is called. + * + * if 'crop' is NULL, subsequently queued buffers won't be cropped. + * + * An error is returned if for instance the crop region is invalid, + * out of the buffer's bound or if the window is invalid. + */ +static inline int native_window_set_crop( + android_native_window_t* window, + android_native_rect_t const * crop) +{ + return window->perform(window, NATIVE_WINDOW_SET_CROP, crop); +} // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index ea68352..d979f00 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -266,9 +266,6 @@ void DisplayHardware::init(uint32_t dpy) if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) { mFlags |= NPOT_EXTENSION; } - if (strstr(gl_extensions, "GL_OES_draw_texture")) { - mFlags |= DRAW_TEXTURE_EXTENSION; - } #ifdef EGL_ANDROID_image_native_buffer if (strstr( gl_extensions, "GL_OES_EGL_image") && (strstr(egl_extensions, "EGL_KHR_image_base") || diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index df046af..897a6ed 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -46,7 +46,6 @@ public: DIRECT_TEXTURE = 0x00000002, COPY_BITS_EXTENSION = 0x00000008, NPOT_EXTENSION = 0x00000100, - DRAW_TEXTURE_EXTENSION = 0x00000200, BUFFER_PRESERVED = 0x00010000, PARTIAL_UPDATES = 0x00020000, // video driver feature SLOW_CONFIG = 0x00040000, // software diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 0a3254d..566428f 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -47,11 +47,6 @@ template <typename T> inline T min(T a, T b) { // --------------------------------------------------------------------------- -const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4; -const char* const Layer::typeID = "Layer"; - -// --------------------------------------------------------------------------- - Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& c, int32_t i) : LayerBaseClient(flinger, display, c, i), @@ -540,9 +535,15 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) mFlinger->signalEvent(); } - if (!mPostedDirtyRegion.isEmpty()) { - reloadTexture( mPostedDirtyRegion ); - } + /* a buffer was posted, so we need to call reloadTexture(), which + * will update our internal data structures (eg: EGLImageKHR or + * texture names). we need to do this even if mPostedDirtyRegion is + * empty -- it's orthogonal to the fact that a new buffer was posted, + * for instance, a degenerate case could be that the user did an empty + * update but repainted the buffer with appropriate content (after a + * resize for instance). + */ + reloadTexture( mPostedDirtyRegion ); } void Layer::unlockPageFlip( @@ -566,7 +567,7 @@ void Layer::unlockPageFlip( } if (visibleRegionScreen.isEmpty()) { // an invisible layer should not hold a freeze-lock - // (because it may never be updated and thereore never release it) + // (because it may never be updated and therefore never release it) mFreezeLock.clear(); } } @@ -579,6 +580,38 @@ void Layer::finishPageFlip() this, mFrontBufferIndex); } + +void Layer::dump(String8& result, char* buffer, size_t SIZE) const +{ + LayerBaseClient::dump(result, buffer, SIZE); + + SharedBufferStack::Statistics stats = lcblk->getStats(); + result.append( lcblk->dump(" ") ); + sp<const GraphicBuffer> buf0(getBuffer(0)); + sp<const GraphicBuffer> buf1(getBuffer(1)); + uint32_t w0=0, h0=0, s0=0; + uint32_t w1=0, h1=0, s1=0; + if (buf0 != 0) { + w0 = buf0->getWidth(); + h0 = buf0->getHeight(); + s0 = buf0->getStride(); + } + if (buf1 != 0) { + w1 = buf1->getWidth(); + h1 = buf1->getHeight(); + s1 = buf1->getStride(); + } + snprintf(buffer, SIZE, + " " + "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," + " freezeLock=%p, dq-q-time=%u us\n", + pixelFormat(), + w0, h0, s0, w1, h1, s1, + getFreezeLock().get(), stats.totalTime); + + result.append(buffer); +} + // --------------------------------------------------------------------------- Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 743afb4..98e30d7 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -46,11 +46,6 @@ const size_t NUM_BUFFERS = 2; class Layer : public LayerBaseClient { public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i); @@ -73,7 +68,7 @@ public: virtual status_t ditch(); // only for debugging - inline sp<GraphicBuffer> getBuffer(int i) { return mBuffers[i]; } + inline sp<GraphicBuffer> getBuffer(int i) const { return mBuffers[i]; } // only for debugging inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; } // only for debugging @@ -81,6 +76,11 @@ public: // only for debugging inline int getFrontBufferIndex() const { return mFrontBufferIndex; } + virtual const char* getTypeId() const { return "Layer"; } + +protected: + virtual void dump(String8& result, char* scratch, size_t size) const; + private: inline sp<GraphicBuffer> getFrontBufferLocked() { return mBuffers[mFrontBufferIndex]; diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index a8b735e..48b0e47 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -38,14 +38,6 @@ namespace android { // --------------------------------------------------------------------------- -const uint32_t LayerBase::typeInfo = 1; -const char* const LayerBase::typeID = "LayerBase"; - -const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2; -const char* const LayerBaseClient::typeID = "LayerBaseClient"; - -// --------------------------------------------------------------------------- - LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) : dpy(display), contentDirty(false), mFlinger(flinger), @@ -54,7 +46,7 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) mOrientation(0), mLeft(0), mTop(0), mTransactionFlags(0), - mPremultipliedAlpha(true), mDebug(false), + mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), mInvalidate(0) { const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); @@ -374,7 +366,7 @@ void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red, Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); glEnable(GL_SCISSOR_TEST); - glVertexPointer(2, GL_FIXED, 0, mVertices); + glVertexPointer(2, GL_FLOAT, 0, mVertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); @@ -418,14 +410,14 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const env = GL_REPLACE; src = GL_SRC_ALPHA; } - const GGLfixed alpha = (s.alpha << 16)/255; - glColor4x(alpha, alpha, alpha, alpha); + const GLfloat alpha = s.alpha * (1.0f/255.0f); + glColor4f(alpha, alpha, alpha, alpha); glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } else { glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glColor4x(0x10000, 0x10000, 0x10000, 0x10000); + glColor4f(1, 1, 1, 1); if (needsBlending()) { GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; glEnable(GL_BLEND); @@ -437,13 +429,11 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); - - //StopWatch watch("GL transformed"); - const GLfixed texCoords[4][2] = { - { 0, 0 }, - { 0, 0x10000 }, - { 0x10000, 0x10000 }, - { 0x10000, 0 } + const GLfloat texCoords[4][2] = { + { 0, 0 }, + { 0, 1 }, + { 1, 1 }, + { 1, 0 } }; glMatrixMode(GL_TEXTURE); @@ -470,8 +460,8 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const } glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FIXED, 0, mVertices); - glTexCoordPointer(2, GL_FIXED, 0, texCoords); + glVertexPointer(2, GL_FLOAT, 0, mVertices); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); while (it != end) { const Rect& r = *it++; @@ -683,6 +673,22 @@ status_t LayerBase::initializeEglImage( return err; } +void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const +{ + const Layer::State& s(drawingState()); + snprintf(buffer, SIZE, + "+ %s %p\n" + " " + "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), " + "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, " + "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", + getTypeId(), this, s.z, tx(), ty(), s.w, s.h, + needsBlending(), needsDithering(), contentDirty, + s.alpha, s.flags, + s.transform[0][0], s.transform[0][1], + s.transform[1][0], s.transform[1][1]); + result.append(buffer); +} // --------------------------------------------------------------------------- @@ -715,13 +721,13 @@ LayerBaseClient::~LayerBaseClient() delete lcblk; } -int32_t LayerBaseClient::serverIndex() const +ssize_t LayerBaseClient::serverIndex() const { sp<Client> client(this->client.promote()); if (client != 0) { return (client->cid<<16)|mIndex; } - return 0xFFFF0000 | mIndex; + return ssize_t(0xFFFF0000 | mIndex); } sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() @@ -750,6 +756,21 @@ void LayerBaseClient::onRemoved() lcblk->setStatus(NO_INIT); } +void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const +{ + LayerBase::dump(result, buffer, SIZE); + + sp<Client> client(this->client.promote()); + snprintf(buffer, SIZE, + " name=%s\n" + " id=0x%08x, client=0x%08x, identity=%u\n", + getName().string(), + clientIndex(), client.get() ? client->cid : 0, + getIdentity()); + + result.append(buffer); +} + // --------------------------------------------------------------------------- LayerBaseClient::Surface::Surface( diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 62ec839..219a53c 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -51,35 +51,9 @@ class SurfaceFlinger; class LayerBase : public RefBase { - // poor man's dynamic_cast below - template<typename T> - struct getTypeInfoOfAnyType { - static uint32_t get() { return T::typeInfo; } - }; - - template<typename T> - struct getTypeInfoOfAnyType<T*> { - static uint32_t get() { return getTypeInfoOfAnyType<T>::get(); } - }; - public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - - template<typename T> - static T dynamicCast(LayerBase* base) { - uint32_t mostDerivedInfo = base->getTypeInfo(); - uint32_t castToInfo = getTypeInfoOfAnyType<T>::get(); - if ((mostDerivedInfo & castToInfo) == castToInfo) - return static_cast<T>(base); - return 0; - } + LayerBase(SurfaceFlinger* flinger, DisplayID display); - - LayerBase(SurfaceFlinger* flinger, DisplayID display); - DisplayID dpy; mutable bool contentDirty; Region visibleRegionScreen; @@ -125,6 +99,9 @@ public: void invalidate(); + virtual const char* getTypeId() const { return "LayerBase"; } + virtual ssize_t serverIndex() const { return -1; } + /** * draw - performs some global clipping optimizations * and calls onDraw(). @@ -217,7 +194,10 @@ public: * current list */ virtual void onRemoved() { }; - + /** always call base class first */ + virtual void dump(String8& result, char* scratch, size_t size) const; + + enum { // flags for doTransaction() eVisibleRegion = 0x00000002, }; @@ -278,7 +258,7 @@ protected: bool mTransformed; bool mUseLinearFiltering; int32_t mOrientation; - GLfixed mVertices[4][2]; + GLfloat mVertices[4][2]; Rect mTransformedBounds; int mLeft; int mTop; @@ -313,10 +293,6 @@ class LayerBaseClient : public LayerBase { public: class Surface; - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } // lcblk is (almost) only accessed from the main SF thread, in the places // where it's not, a reference to Client must be held @@ -331,14 +307,12 @@ public: inline uint32_t getIdentity() const { return mIdentity; } inline int32_t clientIndex() const { return mIndex; } - int32_t serverIndex() const; - sp<Surface> getSurface(); virtual sp<Surface> createSurface() const; - - virtual void onRemoved(); - + virtual ssize_t serverIndex() const; + virtual void onRemoved(); + virtual const char* getTypeId() const { return "LayerBaseClient"; } class Surface : public BnSurface { @@ -373,8 +347,11 @@ public: friend class Surface; +protected: + virtual void dump(String8& result, char* scratch, size_t size) const; + private: - int32_t mIndex; + int32_t mIndex; mutable Mutex mLock; mutable wp<Surface> mClientSurface; // only read diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index 5fd7904..2d77876 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -33,11 +33,6 @@ namespace android { // --------------------------------------------------------------------------- -const uint32_t LayerBlur::typeInfo = LayerBaseClient::typeInfo | 8; -const char* const LayerBlur::typeID = "LayerBlur"; - -// --------------------------------------------------------------------------- - LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i) : LayerBaseClient(flinger, display, client, i), mCacheDirty(true), @@ -206,8 +201,8 @@ void LayerBlur::onDraw(const Region& clip) const const State& s = drawingState(); if (UNLIKELY(s.alpha < 0xFF)) { - const GGLfixed alpha = (s.alpha << 16)/255; - glColor4x(0, 0, 0, alpha); + const GLfloat alpha = s.alpha * (1.0f/255.0f); + glColor4f(0, 0, 0, alpha); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); @@ -225,38 +220,20 @@ void LayerBlur::onDraw(const Region& clip) const glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - if (UNLIKELY(transformed() - || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { - // This is a very rare scenario. - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef(mWidthScale, mHeightScale, 1); - glTranslatef(-x, mYOffset - y, 0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FIXED, 0, mVertices); - glTexCoordPointer(2, GL_FIXED, 0, mVertices); - while (it != end) { - const Rect& r = *it++; - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } else { - // NOTE: this is marginally faster with the software gl, because - // glReadPixels() reads the fb bottom-to-top, however we'll - // skip all the jaccobian computations. - Rect r; - GLint crop[4] = { 0, 0, w, h }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - y = fbHeight - (y + h); - while (it != end) { - const Rect& r = *it++; - const GLint sy = fbHeight - (r.top + r.height()); - glScissor(r.left, sy, r.width(), r.height()); - glDrawTexiOES(x, y, 0, w, h); - } + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(mWidthScale, mHeightScale, 1); + glTranslatef(-x, mYOffset - y, 0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, mVertices); + glTexCoordPointer(2, GL_FLOAT, 0, mVertices); + while (it != end) { + const Rect& r = *it++; + const GLint sy = fbHeight - (r.top + r.height()); + glScissor(r.left, sy, r.width(), r.height()); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h index 5b63dec..380f587 100644 --- a/libs/surfaceflinger/LayerBlur.h +++ b/libs/surfaceflinger/LayerBlur.h @@ -31,11 +31,6 @@ namespace android { class LayerBlur : public LayerBaseClient { public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - LayerBlur(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i); virtual ~LayerBlur(); @@ -43,6 +38,7 @@ public: virtual void onDraw(const Region& clip) const; virtual bool needsBlending() const { return true; } virtual bool isSecure() const { return false; } + virtual const char* getTypeId() const { return "LayerBlur"; } virtual uint32_t doTransaction(uint32_t flags); virtual void setVisibleRegion(const Region& visibleRegion); diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 5c21593..0041a0f 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -39,8 +39,6 @@ namespace android { // --------------------------------------------------------------------------- -const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20; -const char* const LayerBuffer::typeID = "LayerBuffer"; gralloc_module_t const* LayerBuffer::sGrallocModule = 0; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index b176623..243cc43 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -52,17 +52,13 @@ class LayerBuffer : public LayerBaseClient }; public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - LayerBuffer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i); virtual ~LayerBuffer(); virtual void onFirstRef(); virtual bool needsBlending() const; + virtual const char* getTypeId() const { return "LayerBuffer"; } virtual sp<LayerBaseClient::Surface> createSurface() const; virtual status_t ditch(); diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index fd61e30..568fedb 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -30,9 +30,6 @@ namespace android { // --------------------------------------------------------------------------- -const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10; -const char* const LayerDim::typeID = "LayerDim"; - bool LayerDim::sUseTexture; GLuint LayerDim::sTexId; EGLImageKHR LayerDim::sImage; diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h index d4672a1..19a9990 100644 --- a/libs/surfaceflinger/LayerDim.h +++ b/libs/surfaceflinger/LayerDim.h @@ -37,11 +37,6 @@ class LayerDim : public LayerBaseClient static int32_t sWidth; static int32_t sHeight; public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - LayerDim(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client, int32_t i); virtual ~LayerDim(); @@ -49,6 +44,7 @@ public: virtual void onDraw(const Region& clip) const; virtual bool needsBlending() const { return true; } virtual bool isSecure() const { return false; } + virtual const char* getTypeId() const { return "LayerDim"; } static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h); }; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 0722fda..62d829b 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -206,8 +206,8 @@ void SurfaceFlinger::init() property_get("debug.sf.showbackground", value, "0"); mDebugBackground = atoi(value); - LOGI_IF(mDebugRegion, "showupdates enabled"); - LOGI_IF(mDebugBackground, "showbackground enabled"); + LOGI_IF(mDebugRegion, "showupdates enabled"); + LOGI_IF(mDebugBackground, "showbackground enabled"); } SurfaceFlinger::~SurfaceFlinger() @@ -357,7 +357,6 @@ status_t SurfaceFlinger::readyToRun() dcblk->ydpi = hw.getDpiY(); dcblk->fps = hw.getRefreshRate(); dcblk->density = hw.getDensity(); - asm volatile ("":::"memory"); // Initialize OpenGL|ES glActiveTexture(GL_TEXTURE0); @@ -1079,15 +1078,15 @@ status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) { - if (layer == 0) - return BAD_VALUE; ssize_t i = mCurrentState.layersSortedByZ.add( layer, &LayerBase::compareCurrentStateZ); - sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get()); - if (lbc != 0) { - mLayerMap.add(lbc->serverIndex(), lbc); - } - return NO_ERROR; + return (i < 0) ? status_t(i) : status_t(NO_ERROR); +} + +status_t SurfaceFlinger::addClientLayer_l(const sp<LayerBaseClient>& lbc) +{ + ssize_t serverIndex = lbc->serverIndex(); + return mLayerMap.add(serverIndex, lbc); } status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) @@ -1095,10 +1094,9 @@ status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); if (index >= 0) { mLayersRemoved = true; - sp<LayerBaseClient> layer = - LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get()); - if (layer != 0) { - mLayerMap.removeItem(layer->serverIndex()); + ssize_t serverIndex = layerBase->serverIndex(); + if (serverIndex >= 0) { + mLayerMap.removeItem(serverIndex); } return NO_ERROR; } @@ -1298,7 +1296,7 @@ sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked( format = PIXEL_FORMAT_RGBA_8888; break; case PIXEL_FORMAT_OPAQUE: - format = PIXEL_FORMAT_RGB_565; + format = PIXEL_FORMAT_RGBX_8888; break; } @@ -1307,6 +1305,7 @@ sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked( if (LIKELY(err == NO_ERROR)) { layer->initStates(w, h, flags); addLayer_l(layer); + addClientLayer_l(layer); } else { LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); layer.clear(); @@ -1321,6 +1320,7 @@ sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked( sp<LayerBlur> layer = new LayerBlur(this, display, client, id); layer->initStates(w, h, flags); addLayer_l(layer); + addClientLayer_l(layer); return layer; } @@ -1331,6 +1331,7 @@ sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked( sp<LayerDim> layer = new LayerDim(this, display, client, id); layer->initStates(w, h, flags); addLayer_l(layer); + addClientLayer_l(layer); return layer; } @@ -1341,6 +1342,7 @@ sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked( sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id); layer->initStates(w, h, flags); addLayer_l(layer); + addClientLayer_l(layer); return layer; } @@ -1512,83 +1514,17 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) result.append(buffer); } - size_t s = mClientsMap.size(); - char name[64]; - for (size_t i=0 ; i<s ; i++) { - sp<Client> client = mClientsMap.valueAt(i); - sprintf(name, " Client (id=0x%08x)", client->cid); - client->dump(name); - } const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - /*** LayerBase ***/ - const sp<LayerBase>& layer = currentLayers[i]; - const Layer::State& s = layer->drawingState(); - snprintf(buffer, SIZE, - "+ %s %p\n" - " " - "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), " - "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, " - "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", - layer->getTypeID(), layer.get(), - s.z, layer->tx(), layer->ty(), s.w, s.h, - layer->needsBlending(), layer->needsDithering(), - layer->contentDirty, - s.alpha, s.flags, - s.transform[0][0], s.transform[0][1], - s.transform[1][0], s.transform[1][1]); - result.append(buffer); - buffer[0] = 0; - /*** LayerBaseClient ***/ - sp<LayerBaseClient> lbc = - LayerBase::dynamicCast< LayerBaseClient* >(layer.get()); - if (lbc != 0) { - sp<Client> client(lbc->client.promote()); - snprintf(buffer, SIZE, - " name=%s\n", lbc->getName().string()); - result.append(buffer); - snprintf(buffer, SIZE, - " id=0x%08x, client=0x%08x, identity=%u\n", - lbc->clientIndex(), client.get() ? client->cid : 0, - lbc->getIdentity()); - - result.append(buffer); - buffer[0] = 0; - } - /*** Layer ***/ - sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get()); - if (l != 0) { - SharedBufferStack::Statistics stats = l->lcblk->getStats(); - result.append( l->lcblk->dump(" ") ); - sp<const GraphicBuffer> buf0(l->getBuffer(0)); - sp<const GraphicBuffer> buf1(l->getBuffer(1)); - uint32_t w0=0, h0=0, s0=0; - uint32_t w1=0, h1=0, s1=0; - if (buf0 != 0) { - w0 = buf0->getWidth(); - h0 = buf0->getHeight(); - s0 = buf0->getStride(); - } - if (buf1 != 0) { - w1 = buf1->getWidth(); - h1 = buf1->getHeight(); - s1 = buf1->getStride(); - } - snprintf(buffer, SIZE, - " " - "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," - " freezeLock=%p, dq-q-time=%u us\n", - l->pixelFormat(), - w0, h0, s0, w1, h1, s1, - l->getFreezeLock().get(), stats.totalTime); - result.append(buffer); - buffer[0] = 0; - } + const sp<LayerBase>& layer(currentLayers[i]); + layer->dump(result, buffer, SIZE); + const Layer::State& s(layer->drawingState()); s.transparentRegion.dump(result, "transparentRegion"); layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); } + mWormholeRegion.dump(result, "WormholeRegion"); const DisplayHardware& hw(graphicPlane(0).displayHardware()); snprintf(buffer, SIZE, @@ -1601,16 +1537,19 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) " last transaction time : %f us\n", mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); result.append(buffer); + if (inSwapBuffersDuration || !locked) { snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", inSwapBuffersDuration/1000.0); result.append(buffer); } + if (inTransactionDuration || !locked) { snprintf(buffer, SIZE, " transaction time: %f us\n", inTransactionDuration/1000.0); result.append(buffer); } + snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size()); result.append(buffer); const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); @@ -1773,10 +1712,6 @@ sp<LayerBaseClient> Client::getLayerUser(int32_t i) const { return lbc; } -void Client::dump(const char* what) -{ -} - // --------------------------------------------------------------------------- #if 0 #pragma mark - diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index d75dc15..9c8de51 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -73,7 +73,6 @@ public: inline bool isValid(int32_t i) const; sp<LayerBaseClient> getLayerUser(int32_t i) const; - void dump(const char* what); const Vector< wp<LayerBaseClient> >& getLayers() const { return mLayers; @@ -281,6 +280,7 @@ private: void destroyConnection(ClientID cid); sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const; status_t addLayer_l(const sp<LayerBase>& layer); + status_t addClientLayer_l(const sp<LayerBaseClient>& lbc); status_t removeLayer_l(const sp<LayerBase>& layer); status_t purgatorizeLayer_l(const sp<LayerBase>& layer); void free_resources_l(); diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp index 175f989..5e27cc9 100644 --- a/libs/surfaceflinger/Transform.cpp +++ b/libs/surfaceflinger/Transform.cpp @@ -229,14 +229,13 @@ Transform::vec3 Transform::transform(const vec3& v) const { return r; } -void Transform::transform(fixed1616* point, int x, int y) const +void Transform::transform(float* point, int x, int y) const { - const float toFixed = 65536.0f; const mat33& M(mMatrix); vec2 v(x, y); v = transform(v); - point[0] = v[0] * toFixed; - point[1] = v[1] * toFixed; + point[0] = v[0]; + point[1] = v[1]; } Rect Transform::makeBounds(int w, int h) const diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h index 2e5b893..20fa11a 100644 --- a/libs/surfaceflinger/Transform.h +++ b/libs/surfaceflinger/Transform.h @@ -37,8 +37,6 @@ public: explicit Transform(uint32_t orientation); ~Transform(); - typedef int32_t fixed1616; - // FIXME: must match OVERLAY_TRANSFORM_*, pull from hardware.h enum orientation_flags { ROT_0 = 0x00000000, @@ -76,7 +74,7 @@ public: // transform data Rect makeBounds(int w, int h) const; - void transform(fixed1616* point, int x, int y) const; + void transform(float* point, int x, int y) const; Region transform(const Region& reg) const; Transform operator * (const Transform& rhs) const; diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp index a17e8ac..f1aec8a 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -67,19 +67,47 @@ void SharedBufferStack::init(int32_t i) identity = i; } +status_t SharedBufferStack::setCrop(int buffer, const Rect& crop) +{ + if (uint32_t(buffer) >= NUM_BUFFER_MAX) + return BAD_INDEX; + + buffers[buffer].crop.l = uint16_t(crop.left); + buffers[buffer].crop.t = uint16_t(crop.top); + buffers[buffer].crop.r = uint16_t(crop.right); + buffers[buffer].crop.b = uint16_t(crop.bottom); + return NO_ERROR; +} + status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return BAD_INDEX; - // in the current implementation we only send a single rectangle - const Rect bounds(dirty.getBounds()); - FlatRegion& reg(dirtyRegion[buffer]); - reg.count = 1; - reg.rects[0] = uint16_t(bounds.left); - reg.rects[1] = uint16_t(bounds.top); - reg.rects[2] = uint16_t(bounds.right); - reg.rects[3] = uint16_t(bounds.bottom); + FlatRegion& reg(buffers[buffer].dirtyRegion); + if (dirty.isEmpty()) { + reg.count = 0; + return NO_ERROR; + } + + size_t count; + Rect const* r = dirty.getArray(&count); + if (count > FlatRegion::NUM_RECT_MAX) { + const Rect bounds(dirty.getBounds()); + reg.count = 1; + reg.rects[0].l = uint16_t(bounds.left); + reg.rects[0].t = uint16_t(bounds.top); + reg.rects[0].r = uint16_t(bounds.right); + reg.rects[0].b = uint16_t(bounds.bottom); + } else { + reg.count = count; + for (size_t i=0 ; i<count ; i++) { + reg.rects[i].l = uint16_t(r[i].left); + reg.rects[i].t = uint16_t(r[i].top); + reg.rects[i].r = uint16_t(r[i].right); + reg.rects[i].b = uint16_t(r[i].bottom); + } + } return NO_ERROR; } @@ -89,8 +117,27 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const if (uint32_t(buffer) >= NUM_BUFFER_MAX) return res; - const FlatRegion& reg(dirtyRegion[buffer]); - res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3])); + const FlatRegion& reg(buffers[buffer].dirtyRegion); + if (reg.count > FlatRegion::NUM_RECT_MAX) + return res; + + if (reg.count == 1) { + const Rect r( + reg.rects[0].l, + reg.rects[0].t, + reg.rects[0].r, + reg.rects[0].b); + res.set(r); + } else { + for (size_t i=0 ; i<reg.count ; i++) { + const Rect r( + reg.rects[i].l, + reg.rects[i].t, + reg.rects[i].r, + reg.rects[i].b); + res.orSelf(r); + } + } return res; } @@ -280,7 +327,7 @@ ssize_t SharedBufferClient::dequeue() { SharedBufferStack& stack( *mSharedStack ); - if (stack.head == tail && stack.available == 2) { + if (stack.head == tail && stack.available == mNumBuffers) { LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d", tail, stack.head, stack.available, stack.queued); } @@ -346,6 +393,12 @@ bool SharedBufferClient::needNewBuffer(int buffer) const return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0; } +status_t SharedBufferClient::setCrop(int buffer, const Rect& crop) +{ + SharedBufferStack& stack( *mSharedStack ); + return stack.setCrop(buffer, crop); +} + status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg) { SharedBufferStack& stack( *mSharedStack ); @@ -363,7 +416,7 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient, mSharedStack->available = num; mSharedStack->queued = 0; mSharedStack->reallocMask = 0; - memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion)); + memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers)); } ssize_t SharedBufferServer::retireAndLock() diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index 5dd75c3..057d211 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -17,8 +17,6 @@ #define LOG_TAG "Surface" #include <stdint.h> -#include <unistd.h> -#include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> @@ -28,8 +26,6 @@ #include <utils/CallStack.h> #include <utils/Log.h> -#include <pixelflinger/pixelflinger.h> - #include <binder/IPCThreadState.h> #include <binder/IMemory.h> @@ -55,6 +51,8 @@ static status_t copyBlt( const sp<GraphicBuffer>& src, const Region& reg) { + // src and dst with, height and format must be identical. no verification + // is done here. status_t err; uint8_t const * src_bits = NULL; err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); @@ -67,7 +65,6 @@ static status_t copyBlt( Region::const_iterator head(reg.begin()); Region::const_iterator tail(reg.end()); if (head != tail && src_bits && dst_bits) { - // NOTE: dst and src must be the same format const size_t bpp = bytesPerPixel(src->format); const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; @@ -354,7 +351,6 @@ void Surface::init() // be default we request a hardware surface mUsage = GRALLOC_USAGE_HW_RENDER; mConnected = 0; - mNeedFullUpdate = false; } Surface::~Surface() @@ -495,9 +491,12 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) // below we make sure we AT LEAST have the usage flags we want const uint32_t usage(getUsage()); const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]); + + // Always call needNewBuffer(), since it clears the needed buffers flags + bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx); if (backBuffer == 0 || ((uint32_t(backBuffer->usage) & usage) != usage) || - mSharedBufferClient->needNewBuffer(bufIdx)) + needNewBuffer) { err = getBufferLocked(bufIdx, usage); LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)", @@ -549,6 +548,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) } int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex(); + mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop); mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); err = mSharedBufferClient->queue(bufIdx); LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err)); @@ -578,6 +578,10 @@ int Surface::query(int what, int* value) int Surface::perform(int operation, va_list args) { + status_t err = validate(); + if (err != NO_ERROR) + return err; + int res = NO_ERROR; switch (operation) { case NATIVE_WINDOW_SET_USAGE: @@ -589,6 +593,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_DISCONNECT: res = dispatch_disconnect( args ); break; + case NATIVE_WINDOW_SET_CROP: + res = dispatch_crop( args ); + break; default: res = NAME_NOT_FOUND; break; @@ -608,6 +615,10 @@ int Surface::dispatch_disconnect(va_list args) { int api = va_arg(args, int); return disconnect( api ); } +int Surface::dispatch_crop(va_list args) { + android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); + return crop( reinterpret_cast<Rect const*>(rect) ); +} void Surface::setUsage(uint32_t reqUsage) @@ -666,6 +677,14 @@ int Surface::getConnectedApi() const return mConnected; } +int Surface::crop(Rect const* rect) +{ + Mutex::Autolock _l(mSurfaceLock); + // TODO: validate rect size + mNextBufferCrop = *rect; + return NO_ERROR; +} + // ---------------------------------------------------------------------------- @@ -711,37 +730,38 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)", backBuffer->getIndex(), strerror(-err)); if (err == NO_ERROR) { - // we handle copy-back here... - const Rect bounds(backBuffer->width, backBuffer->height); - Region scratch(bounds); + const Region boundsRegion(bounds); + Region scratch(boundsRegion); Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); + newDirtyRegion &= boundsRegion; - if (mNeedFullUpdate) { - // reset newDirtyRegion to bounds when a buffer is reallocated - // it would be better if this information was associated with - // the buffer and made available to outside of Surface. - // This will do for now though. - mNeedFullUpdate = false; - newDirtyRegion.set(bounds); - } else { - newDirtyRegion.andSelf(bounds); - } - + // figure out if we can copy the frontbuffer back const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); - if (frontBuffer !=0 && - backBuffer->width == frontBuffer->width && - backBuffer->height == frontBuffer->height && - !(mFlags & ISurfaceComposer::eDestroyBackbuffer)) - { + const bool canCopyBack = (frontBuffer != 0 && + backBuffer->width == frontBuffer->width && + backBuffer->height == frontBuffer->height && + backBuffer->format == frontBuffer->format && + !(mFlags & ISurfaceComposer::eDestroyBackbuffer)); + + // the dirty region we report to surfaceflinger is the one + // given by the user (as opposed to the one *we* return to the + // user). + mDirtyRegion = newDirtyRegion; + + if (canCopyBack) { + // copy the area that is invalid and not repainted this round const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); - if (!copyback.isEmpty() && frontBuffer!=0) { - // copy front to back + if (!copyback.isEmpty()) copyBlt(backBuffer, frontBuffer, copyback); - } + } else { + // if we can't copy-back anything, modify the user's dirty + // region to make sure they redraw the whole buffer + newDirtyRegion = boundsRegion; } - mDirtyRegion = newDirtyRegion; + // keep track of the are of the buffer that is "clean" + // (ie: that will be redrawn) mOldDirtyRegion = newDirtyRegion; void* vaddr; @@ -820,7 +840,6 @@ status_t Surface::getBufferLocked(int index, int usage) if (err == NO_ERROR) { currentBuffer = buffer; currentBuffer->setIndex(index); - mNeedFullUpdate = true; } } else { err = err<0 ? err : NO_MEMORY; diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index 6ae7e74..d51664d 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -15,6 +15,8 @@ ** limitations under the License. */ +#define LOG_TAG "GraphicBufferAllocator" + #include <cutils/log.h> #include <utils/Singleton.h> @@ -61,9 +63,9 @@ void GraphicBufferAllocator::dump(String8& result) const const size_t c = list.size(); for (size_t i=0 ; i<c ; i++) { const alloc_rec_t& rec(list.valueAt(i)); - snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u x %4u | %2d | 0x%08x\n", + snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n", list.keyAt(i), rec.size/1024.0f, - rec.w, rec.h, rec.format, rec.usage); + rec.w, rec.s, rec.h, rec.format, rec.usage); result.append(buffer); total += rec.size; } @@ -71,16 +73,13 @@ void GraphicBufferAllocator::dump(String8& result) const result.append(buffer); } -static inline uint32_t clamp(uint32_t c) { - return c>0 ? c : 1; -} - status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, buffer_handle_t* handle, int32_t* stride) { - // make sure to not allocate a 0 x 0 buffer - w = clamp(w); - h = clamp(h); + // make sure to not allocate a N x 0 or 0 x N buffer, since this is + // allowed from an API stand-point allocate a 1x1 buffer instead. + if (!w || !h) + w = h = 1; // we have a h/w allocator and h/w buffer is requested status_t err; @@ -100,9 +99,9 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma alloc_rec_t rec; rec.w = w; rec.h = h; + rec.s = *stride; rec.format = format; rec.usage = usage; - rec.vaddr = 0; rec.size = h * stride[0] * bytesPerPixel(format); list.add(*handle, rec); } else { diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 89b3e1f..e6cf792 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -239,7 +239,7 @@ struct tls_t // ---------------------------------------------------------------------------- -egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS]; +static egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS]; static egl_display_t gDisplay[NUM_DISPLAYS]; static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t gEGLThreadLocalStorageKey = -1; diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h index 1fba209..c8f529a 100644 --- a/opengl/libs/egl_impl.h +++ b/opengl/libs/egl_impl.h @@ -31,6 +31,7 @@ namespace android { struct egl_connection_t { + inline egl_connection_t() : dso(0) { } void * dso; gl_hooks_t * hooks[2]; EGLint major; diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java index ce522c8..ce40b5d 100644 --- a/vpn/java/android/net/vpn/VpnManager.java +++ b/vpn/java/android/net/vpn/VpnManager.java @@ -85,7 +85,8 @@ public class VpnManager { // TODO(oam): Test VPN when EFS is enabled (will do later)... public static String getProfilePath() { - return Environment.getDataDirectory().getPath() + PROFILES_PATH; + // This call will return the correct path if Encrypted FS is enabled or not. + return Environment.getSecureDataDirectory().getPath() + PROFILES_PATH; } /** |