summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libs/gui/Surface.cpp6
-rw-r--r--libs/ui/GraphicBufferMapper.cpp15
-rw-r--r--services/surfaceflinger/RenderEngine/Mesh.cpp30
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp29
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h4
5 files changed, 69 insertions, 15 deletions
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 5d81f10..35aa7c7 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -267,6 +267,9 @@ int Surface::cancelBuffer(android_native_buffer_t* buffer,
Mutex::Autolock lock(mMutex);
int i = getSlotFromBufferLocked(buffer);
if (i < 0) {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
return i;
}
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
@@ -308,6 +311,9 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
}
int i = getSlotFromBufferLocked(buffer);
if (i < 0) {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
return i;
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 31bfb2d..90a1c11 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -131,8 +131,10 @@ status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
bounds.left, bounds.top, bounds.width(), bounds.height(),
vaddr, fenceFd);
} else {
- sync_wait(fenceFd, -1);
- close(fenceFd);
+ if (fenceFd >= 0) {
+ sync_wait(fenceFd, -1);
+ close(fenceFd);
+ }
err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
vaddr);
@@ -154,12 +156,17 @@ status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
static_cast<int>(usage), bounds.left, bounds.top,
bounds.width(), bounds.height(), ycbcr, fenceFd);
} else if (mAllocMod->lock_ycbcr != NULL) {
- sync_wait(fenceFd, -1);
- close(fenceFd);
+ if (fenceFd >= 0) {
+ sync_wait(fenceFd, -1);
+ close(fenceFd);
+ }
err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
ycbcr);
} else {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
return -EINVAL; // do not log failure
}
diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp
index 3f50cb0..ffd9be2 100644
--- a/services/surfaceflinger/RenderEngine/Mesh.cpp
+++ b/services/surfaceflinger/RenderEngine/Mesh.cpp
@@ -16,14 +16,40 @@
#include "Mesh.h"
+#include <utils/Log.h>
+
namespace android {
Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize)
: mVertexCount(vertexCount), mVertexSize(vertexSize), mTexCoordsSize(texCoordSize),
mPrimitive(primitive)
{
- mVertices = new float[(vertexSize + texCoordSize) * vertexCount];
- mStride = mVertexSize + mTexCoordsSize;
+ if (vertexCount == 0) {
+ mVertices = new float[1];
+ mVertices[0] = 0.0f;
+ mStride = 0;
+ return;
+ }
+
+ size_t stride = vertexSize + texCoordSize;
+ size_t remainder = (stride * vertexCount) / vertexCount;
+ // Since all of the input parameters are unsigned, if stride is less than
+ // either vertexSize or texCoordSize, it must have overflowed. remainder
+ // will be equal to stride as long as stride * vertexCount doesn't overflow.
+ if ((stride < vertexSize) || (remainder != stride)) {
+ ALOGE("Overflow in Mesh(..., %zu, %zu, %zu)", vertexCount, vertexSize,
+ texCoordSize);
+ mVertices = new float[1];
+ mVertices[0] = 0.0f;
+ mVertexCount = 0;
+ mVertexSize = 0;
+ mTexCoordsSize = 0;
+ mStride = 0;
+ return;
+ }
+
+ mVertices = new float[stride * vertexCount];
+ mStride = stride;
}
Mesh::~Mesh() {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1419557..0d57ae5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2018,18 +2018,25 @@ void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Regio
engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
}
-void SurfaceFlinger::addClientLayer(const sp<Client>& client,
+status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc)
{
+ // add this layer to the current state list
+ {
+ Mutex::Autolock _l(mStateLock);
+ if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
+ return NO_MEMORY;
+ }
+ mCurrentState.layersSortedByZ.add(lbc);
+ mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
+ }
+
// attach this layer to the client
client->attachLayer(handle, lbc);
- // add this layer to the current state list
- Mutex::Autolock _l(mStateLock);
- mCurrentState.layersSortedByZ.add(lbc);
- mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
+ return NO_ERROR;
}
status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
@@ -2286,10 +2293,16 @@ status_t SurfaceFlinger::createLayer(
break;
}
- if (result == NO_ERROR) {
- addClientLayer(client, *handle, *gbp, layer);
- setTransactionFlags(eTransactionNeeded);
+ if (result != NO_ERROR) {
+ return result;
}
+
+ result = addClientLayer(client, *handle, *gbp, layer);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ setTransactionFlags(eTransactionNeeded);
return result;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d2654d4..3759a92 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -144,6 +144,8 @@ private:
// every half hour.
enum { LOG_FRAME_STATS_PERIOD = 30*60*60 };
+ static const size_t MAX_LAYERS = 4096;
+
// We're reference counted, never destroy SurfaceFlinger directly
virtual ~SurfaceFlinger();
@@ -305,7 +307,7 @@ private:
status_t removeLayer(const sp<Layer>& layer);
// add a layer to SurfaceFlinger
- void addClientLayer(const sp<Client>& client,
+ status_t addClientLayer(const sp<Client>& client,
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc);