auto import from //branches/cupcake/...@130745
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index c9cebf4..fc0a603 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -25,6 +25,9 @@
#include <utils/Log.h>
#include <utils/StopWatch.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
#include <ui/PixelFormat.h>
#include <ui/EGLDisplaySurface.h>
@@ -100,6 +103,15 @@
source->unregisterBuffers();
}
+Transform LayerBuffer::getDrawingStateTransform() const
+{
+ Transform tr(LayerBaseClient::getDrawingStateTransform());
+ sp<Source> source(getSource());
+ if (source != 0)
+ source->updateTransform(&tr);
+ return tr;
+}
+
uint32_t LayerBuffer::doTransaction(uint32_t flags)
{
sp<Source> source(getSource());
@@ -132,15 +144,13 @@
/**
* This creates a "buffer" source for this surface
*/
-status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride,
- PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
+status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
{
Mutex::Autolock _l(mLock);
if (mSource != 0)
return INVALID_OPERATION;
- sp<BufferSource> source = new BufferSource(*this, w, h,
- hstride, vstride, format, memoryHeap);
+ sp<BufferSource> source = new BufferSource(*this, buffers);
status_t result = source->getStatus();
if (result == NO_ERROR) {
@@ -194,13 +204,39 @@
mOwner = 0;
}
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(
- int w, int h, int hs, int vs,
- PixelFormat format, const sp<IMemoryHeap>& heap)
+status_t LayerBuffer::SurfaceBuffer::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch (code) {
+ case REGISTER_BUFFERS:
+ case UNREGISTER_BUFFERS:
+ case CREATE_OVERLAY:
+ {
+ // codes that require permission check
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ const int self_pid = getpid();
+ if (LIKELY(pid != self_pid)) {
+ // we're called from a different process, do the real check
+ if (!checkCallingPermission(
+ String16("android.permission.ACCESS_SURFACE_FLINGER")))
+ {
+ const int uid = ipc->getCallingUid();
+ LOGE("Permission Denial: "
+ "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+ return PERMISSION_DENIED;
+ }
+ }
+ }
+ }
+ return LayerBaseClient::Surface::onTransact(code, data, reply, flags);
+}
+
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
{
LayerBuffer* owner(getOwner());
if (owner)
- return owner->registerBuffers(w, h, hs, vs, format, heap);
+ return owner->registerBuffers(buffers);
return NO_INIT;
}
@@ -237,23 +273,20 @@
// LayerBuffer::Buffer
// ============================================================================
-LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
- int w, int h, int hs, int vs, int f)
-: mHeap(heap)
+LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset)
+ : mBufferHeap(buffers)
{
NativeBuffer& src(mNativeBuffer);
src.crop.l = 0;
src.crop.t = 0;
- src.crop.r = w;
- src.crop.b = h;
- src.img.w = hs ?: w;
- src.img.h = vs ?: h;
- src.img.format = f;
+ src.crop.r = buffers.w;
+ src.crop.b = buffers.h;
+ src.img.w = buffers.hor_stride ?: buffers.w;
+ src.img.h = buffers.ver_stride ?: buffers.h;
+ src.img.format = buffers.format;
src.img.offset = offset;
- src.img.base = heap->base();
- src.img.fd = heap->heapID();
- // FIXME: make sure this buffer lies within the heap, in which case, set
- // mHeap to null
+ src.img.base = buffers.heap->base();
+ src.img.fd = buffers.heap->heapID();
}
LayerBuffer::Buffer::~Buffer()
@@ -283,41 +316,53 @@
}
void LayerBuffer::Source::unregisterBuffers() {
}
+void LayerBuffer::Source::updateTransform(Transform* tr) const {
+}
// ---------------------------------------------------------------------------
LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
- int w, int h, int hstride, int vstride,
- PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
- : Source(layer), mStatus(NO_ERROR), mTextureName(-1U)
+ const ISurface::BufferHeap& buffers)
+ : Source(layer), mStatus(NO_ERROR),
+ mBufferSize(0), mTextureName(-1U)
{
- if (memoryHeap == NULL) {
+ if (buffers.heap == NULL) {
// this is allowed, but in this case, it is illegal to receive
// postBuffer(). The surface just erases the framebuffer with
// fully transparent pixels.
- mHeap.clear();
- mWidth = w;
- mHeight = h;
+ mBufferHeap = buffers;
mLayer.setNeedsBlending(false);
return;
}
- status_t err = (memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+ status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
if (err != NO_ERROR) {
+ LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
+ mStatus = err;
+ return;
+ }
+
+ PixelFormatInfo info;
+ err = getPixelFormatInfo(buffers.format, &info);
+ if (err != NO_ERROR) {
+ LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
+ buffers.format, strerror(err));
mStatus = err;
return;
}
- // TODO: validate format/parameters
- mHeap = memoryHeap;
- mWidth = w;
- mHeight = h;
- mHStride = hstride;
- mVStride = vstride;
- mFormat = format;
- PixelFormatInfo info;
- getPixelFormatInfo(format, &info);
- mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
+ if (buffers.hor_stride<0 || buffers.ver_stride<0) {
+ LOGE("LayerBuffer::BufferSource: invalid parameters "
+ "(w=%d, h=%d, xs=%d, ys=%d)",
+ buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
+ mStatus = BAD_VALUE;
+ return;
+ }
+
+ mBufferHeap = buffers;
+ mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
+ mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
+ mLayer.forceVisibilityTransaction();
}
LayerBuffer::BufferSource::~BufferSource()
@@ -329,21 +374,24 @@
void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
{
- sp<IMemoryHeap> heap;
- int w, h, hs, vs, f;
+ ISurface::BufferHeap buffers;
{ // scope for the lock
Mutex::Autolock _l(mLock);
- w = mWidth;
- h = mHeight;
- hs= mHStride;
- vs= mVStride;
- f = mFormat;
- heap = mHeap;
+ buffers = mBufferHeap;
+ if (buffers.heap != 0) {
+ const size_t memorySize = buffers.heap->getSize();
+ if ((size_t(offset) + mBufferSize) > memorySize) {
+ LOGE("LayerBuffer::BufferSource::postBuffer() "
+ "invalid buffer (offset=%d, size=%d, heap-size=%d",
+ int(offset), int(mBufferSize), int(memorySize));
+ return;
+ }
+ }
}
sp<Buffer> buffer;
- if (heap != 0) {
- buffer = new LayerBuffer::Buffer(heap, offset, w, h, hs, vs, f);
+ if (buffers.heap != 0) {
+ buffer = new LayerBuffer::Buffer(buffers, offset);
if (buffer->getStatus() != NO_ERROR)
buffer.clear();
setBuffer(buffer);
@@ -354,7 +402,7 @@
void LayerBuffer::BufferSource::unregisterBuffers()
{
Mutex::Autolock _l(mLock);
- mHeap.clear();
+ mBufferHeap.heap.clear();
mBuffer.clear();
mLayer.invalidate();
}
@@ -371,6 +419,17 @@
mBuffer = buffer;
}
+void LayerBuffer::BufferSource::updateTransform(Transform* tr) const
+{
+ uint32_t bufTransform = mBufferHeap.transform;
+ // TODO: handle all transforms
+ if (bufTransform == ISurface::BufferHeap::ROT_90) {
+ Transform rot90;
+ rot90.set(0, -1, 1, 0);
+ *tr = (*tr) * rot90;
+ }
+}
+
void LayerBuffer::BufferSource::onDraw(const Region& clip) const
{
sp<Buffer> buffer(getBuffer());
@@ -452,11 +511,13 @@
region_iterator it(clip);
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, mLayer.getOrientation());
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
- copybit->set_parameter(copybit, COPYBIT_DITHER,
- s.flags & ISurfaceComposer::eLayerDither ?
- COPYBIT_ENABLE : COPYBIT_DISABLE);
+ copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+
err = copybit->stretch(copybit,
&dst, &src.img, &drect, &src.crop, &it);
+ if (err != NO_ERROR) {
+ LOGE("copybit failed (%s)", strerror(err));
+ }
}
if (!can_use_copybit || err) {