diff options
author | Mathias Agopian <mathias@google.com> | 2009-07-13 18:29:59 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-07-13 18:29:59 -0700 |
commit | 8d9a5eff4262b80513cb04dec0e731be8b64bb2b (patch) | |
tree | 7cee20a18c81b000dfc10dd86bcad4265ac6d584 /libs/ui/Surface.cpp | |
parent | b9cb7c970b04c59d490ed480635a93df63eadeb9 (diff) | |
download | frameworks_base-8d9a5eff4262b80513cb04dec0e731be8b64bb2b.zip frameworks_base-8d9a5eff4262b80513cb04dec0e731be8b64bb2b.tar.gz frameworks_base-8d9a5eff4262b80513cb04dec0e731be8b64bb2b.tar.bz2 |
fix [1964315] crash in the surface.cpp while browsing
Diffstat (limited to 'libs/ui/Surface.cpp')
-rw-r--r-- | libs/ui/Surface.cpp | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index b8b428f..aef47fd 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -88,6 +88,13 @@ status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr) status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) { + if (rect.left < 0 || rect.right > this->width || + rect.top < 0 || rect.bottom > this->height) { + LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", + rect.left, rect.top, rect.right, rect.bottom, + this->width, this->height); + return BAD_VALUE; + } status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); return res; } @@ -112,28 +119,30 @@ status_t SurfaceBuffer::writeToParcel(Parcel* reply, // ---------------------------------------------------------------------- -static void copyBlt( +static status_t copyBlt( const sp<SurfaceBuffer>& dst, const sp<SurfaceBuffer>& src, const Region& reg) { - uint8_t const * src_bits; - src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); + status_t err; + uint8_t const * src_bits = NULL; + err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); + LOGE_IF(err, "error locking src buffer %s", strerror(-err)); - uint8_t* dst_bits; - dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); - - size_t c; - Rect const* const rects = reg.getArray(&c); - - if (c) { + uint8_t* dst_bits = NULL; + err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); + LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); + + 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; - for (size_t i=0 ; i<c ; i++) { - const Rect& r = rects[i]; + while (head != tail) { + const Rect& r(*head++); ssize_t h = r.height(); if (h <= 0) continue; size_t size = r.width() * bpp; @@ -151,8 +160,13 @@ static void copyBlt( } } - src->unlock(); - dst->unlock(); + if (src_bits) + src->unlock(); + + if (dst_bits) + dst->unlock(); + + return err; } // ============================================================================ @@ -602,8 +616,11 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) newDirtyRegion.set(bounds); } else { newDirtyRegion.andSelf(bounds); - if (!(lcblk->flags & eNoCopyBack)) { - const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]); + const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]); + if (backBuffer->width == frontBuffer->width && + backBuffer->height == frontBuffer->height && + !(lcblk->flags & eNoCopyBack)) + { const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); if (!copyback.isEmpty() && frontBuffer!=0) { // copy front to back |