Merge "Track camera and flashlight usage in battery stats." into mnc-dev
diff --git a/include/android/configuration.h b/include/android/configuration.h
index be00066..7573cca 100644
--- a/include/android/configuration.h
+++ b/include/android/configuration.h
@@ -78,6 +78,10 @@
ACONFIGURATION_SCREENLONG_NO = 0x1,
ACONFIGURATION_SCREENLONG_YES = 0x2,
+ ACONFIGURATION_SCREENROUND_ANY = 0x00,
+ ACONFIGURATION_SCREENROUND_NO = 0x1,
+ ACONFIGURATION_SCREENROUND_YES = 0x2,
+
ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00,
ACONFIGURATION_UI_MODE_TYPE_NORMAL = 0x01,
ACONFIGURATION_UI_MODE_TYPE_DESK = 0x02,
@@ -115,6 +119,7 @@
ACONFIGURATION_UI_MODE = 0x1000,
ACONFIGURATION_SMALLEST_SCREEN_SIZE = 0x2000,
ACONFIGURATION_LAYOUTDIR = 0x4000,
+ ACONFIGURATION_SCREEN_ROUND = 0x8000,
ACONFIGURATION_MNC_ZERO = 0xffff,
};
@@ -288,6 +293,16 @@
void AConfiguration_setScreenLong(AConfiguration* config, int32_t screenLong);
/**
+ * Return the current ACONFIGURATION_SCREENROUND_* set in the configuration.
+ */
+int32_t AConfiguration_getScreenRound(AConfiguration* config);
+
+/**
+ * Set the current screen round in the configuration.
+ */
+void AConfiguration_setScreenRound(AConfiguration* config, int32_t screenRound);
+
+/**
* Return the current ACONFIGURATION_UI_MODE_TYPE_* set in the configuration.
*/
int32_t AConfiguration_getUiModeType(AConfiguration* config);
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index 000ef0e..145efe6 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -72,7 +72,13 @@
// to set by queueBuffer each time this slot is queued. This value
// is guaranteed to be monotonically increasing for each newly
// acquired buffer.
- int64_t mTimestamp;
+ union {
+ int64_t mTimestamp;
+ struct {
+ uint32_t mTimestampLo;
+ uint32_t mTimestampHi;
+ };
+ };
// mIsAutoTimestamp indicates whether mTimestamp was generated
// automatically when the buffer was queued.
@@ -84,7 +90,13 @@
android_dataspace mDataSpace;
// mFrameNumber is the number of the queued frame for this slot.
- uint64_t mFrameNumber;
+ union {
+ uint64_t mFrameNumber;
+ struct {
+ uint32_t mFrameNumberLo;
+ uint32_t mFrameNumberHi;
+ };
+ };
union {
// mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h
index 930fabf..56c7a3f 100644
--- a/include/gui/BufferItemConsumer.h
+++ b/include/gui/BufferItemConsumer.h
@@ -86,21 +86,6 @@
status_t releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence = Fence::NO_FENCE);
- // setDefaultBufferSize is used to set the size of buffers returned by
- // requestBuffers when a with and height of zero is requested.
- status_t setDefaultBufferSize(uint32_t w, uint32_t h);
-
- // setDefaultBufferFormat allows the BufferQueue to create
- // GraphicBuffers of a defaultFormat if no format is specified
- // in dequeueBuffer
- status_t setDefaultBufferFormat(PixelFormat defaultFormat);
-
- // setDefaultBufferDataSpace allows the BufferQueue to create
- // GraphicBuffers of a defaultDataSpace if no data space is specified
- // in queueBuffer.
- // The initial default is HAL_DATASPACE_UNKNOWN
- status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
-
};
} // namespace android
diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h
index 46c603d..9307a26 100644
--- a/include/gui/ConsumerBase.h
+++ b/include/gui/ConsumerBase.h
@@ -76,6 +76,15 @@
// See IGraphicBufferConsumer::detachBuffer
status_t detachBuffer(int slot);
+ // See IGraphicBufferConsumer::setDefaultBufferSize
+ status_t setDefaultBufferSize(uint32_t width, uint32_t height);
+
+ // See IGraphicBufferConsumer::setDefaultBufferFormat
+ status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+
+ // See IGraphicBufferConsumer::setDefaultBufferDataSpace
+ status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
+
private:
ConsumerBase(const ConsumerBase&);
void operator=(const ConsumerBase&);
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index c99ab29..3b07a31 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -80,23 +80,6 @@
// log messages.
void setName(const String8& name);
- // setDefaultBufferSize is used to set the size of buffers returned by
- // requestBuffers when a width and height of zero is requested.
- // A call to setDefaultBufferSize() may trigger requestBuffers() to
- // be called from the client. Default size is 1x1.
- status_t setDefaultBufferSize(uint32_t width, uint32_t height);
-
- // setDefaultBufferFormat allows CpuConsumer's BufferQueue to create buffers
- // of a defaultFormat if no format is specified by producer.
- // The initial default is PIXEL_FORMAT_RGBA_8888.
- status_t setDefaultBufferFormat(PixelFormat defaultFormat);
-
- // setDefaultBufferDataSpace allows the BufferQueue to create
- // GraphicBuffers of a defaultDataSpace if no data space is specified
- // in queueBuffer.
- // The initial default is HAL_DATASPACE_UNKNOWN
- status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
-
// Gets the next graphics buffer from the producer and locks it for CPU use,
// filling out the passed-in locked buffer structure with the native pointer
// and metadata. Returns BAD_VALUE if no new buffer is available, and
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 015866b..c1cfb1e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -451,7 +451,7 @@
// Count objects in range
for (int i = 0; i < (int) size; i++) {
size_t off = objects[i];
- if ((off >= offset) && (off < offset + len)) {
+ if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
if (firstIndex == -1) {
firstIndex = i;
}
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index 5793d40..8f64ae0 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -46,15 +46,16 @@
}
size_t BufferItem::getPodSize() const {
- // Must align<8> before writing these fields for this to be correct
size_t size = 0;
addAligned(size, mCrop);
addAligned(size, mTransform);
addAligned(size, mScalingMode);
- addAligned(size, mTimestamp);
+ addAligned(size, mTimestampLo);
+ addAligned(size, mTimestampHi);
addAligned(size, mIsAutoTimestamp);
addAligned(size, mDataSpace);
- addAligned(size, mFrameNumber);
+ addAligned(size, mFrameNumberLo);
+ addAligned(size, mFrameNumberHi);
addAligned(size, mSlot);
addAligned(size, mIsDroppable);
addAligned(size, mAcquireCalled);
@@ -126,9 +127,6 @@
if (err) return err;
FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
- // Must align<8> so that getPodSize returns the correct value
- size -= FlattenableUtils::align<8>(buffer);
-
// Check we still have enough space
if (size < getPodSize()) {
return NO_MEMORY;
@@ -137,10 +135,12 @@
writeAligned(buffer, size, mCrop);
writeAligned(buffer, size, mTransform);
writeAligned(buffer, size, mScalingMode);
- writeAligned(buffer, size, mTimestamp);
+ writeAligned(buffer, size, mTimestampLo);
+ writeAligned(buffer, size, mTimestampHi);
writeAligned(buffer, size, mIsAutoTimestamp);
writeAligned(buffer, size, mDataSpace);
- writeAligned(buffer, size, mFrameNumber);
+ writeAligned(buffer, size, mFrameNumberLo);
+ writeAligned(buffer, size, mFrameNumberHi);
writeAligned(buffer, size, mSlot);
writeAligned(buffer, size, mIsDroppable);
writeAligned(buffer, size, mAcquireCalled);
@@ -183,9 +183,6 @@
if (err) return err;
FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
- // Must align<8> so that getPodSize returns the correct value
- size -= FlattenableUtils::align<8>(buffer);
-
// Check we still have enough space
if (size < getPodSize()) {
return NO_MEMORY;
@@ -194,10 +191,12 @@
readAligned(buffer, size, mCrop);
readAligned(buffer, size, mTransform);
readAligned(buffer, size, mScalingMode);
- readAligned(buffer, size, mTimestamp);
+ readAligned(buffer, size, mTimestampLo);
+ readAligned(buffer, size, mTimestampHi);
readAligned(buffer, size, mIsAutoTimestamp);
readAligned(buffer, size, mDataSpace);
- readAligned(buffer, size, mFrameNumber);
+ readAligned(buffer, size, mFrameNumberLo);
+ readAligned(buffer, size, mFrameNumberHi);
readAligned(buffer, size, mSlot);
readAligned(buffer, size, mIsDroppable);
readAligned(buffer, size, mAcquireCalled);
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 194121f..578b8d9 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -100,20 +100,4 @@
return err;
}
-status_t BufferItemConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) {
- Mutex::Autolock _l(mMutex);
- return mConsumer->setDefaultBufferSize(w, h);
-}
-
-status_t BufferItemConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
- Mutex::Autolock _l(mMutex);
- return mConsumer->setDefaultBufferFormat(defaultFormat);
-}
-
-status_t BufferItemConsumer::setDefaultBufferDataSpace(
- android_dataspace defaultDataSpace) {
- Mutex::Autolock _l(mMutex);
- return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
-}
-
} // namespace android
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 2cf7433..e318484 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -914,8 +914,8 @@
mCore->mSidebandStream.clear();
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
- } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("disconnect(P): still connected to another API "
+ } else {
+ BQ_LOGE("disconnect(P): connected to another API "
"(cur=%d req=%d)", mCore->mConnectedApi, api);
status = BAD_VALUE;
}
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 0e42daf..04ab06b 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -198,6 +198,22 @@
return result;
}
+status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferSize(width, height);
+}
+
+status_t ConsumerBase::setDefaultBufferFormat(PixelFormat defaultFormat) {
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferFormat(defaultFormat);
+}
+
+status_t ConsumerBase::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
void ConsumerBase::dump(String8& result) const {
dump(result, "");
}
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index eb39469..e29b740 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -56,25 +56,6 @@
mConsumer->setConsumerName(name);
}
-status_t CpuConsumer::setDefaultBufferSize(uint32_t width, uint32_t height)
-{
- Mutex::Autolock _l(mMutex);
- return mConsumer->setDefaultBufferSize(width, height);
-}
-
-status_t CpuConsumer::setDefaultBufferFormat(PixelFormat defaultFormat)
-{
- Mutex::Autolock _l(mMutex);
- return mConsumer->setDefaultBufferFormat(defaultFormat);
-}
-
-status_t CpuConsumer::setDefaultBufferDataSpace(
- android_dataspace defaultDataSpace)
-{
- Mutex::Autolock _l(mMutex);
- return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
-}
-
static bool isPossiblyYUV(PixelFormat format) {
switch (static_cast<int>(format)) {
case HAL_PIXEL_FORMAT_RGBA_8888:
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 09b63a1..3009989 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -59,6 +59,9 @@
if (result == NO_ERROR) {
graphicBuffer = new GraphicBuffer();
result = reply.read(*graphicBuffer);
+ if (result != NO_ERROR) {
+ graphicBuffer.clear();
+ }
// reply.readStrongBinder();
// here we don't even have to read the BufferReference from
// the parcel, it'll die with the parcel.
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 35aa7c7..04ac0f4 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -335,10 +335,14 @@
// the origin being in the bottom-left corner. Here we flip to the
// convention that the rest of the system uses (top-left corner) by
// subtracting all top/bottom coordinates from the buffer height.
+ int height = buffer->height;
+ if ((mTransform ^ mStickyTransform) & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ height = buffer->width;
+ }
Region flippedRegion;
for (auto rect : mDirtyRegion) {
- auto top = buffer->height - rect.bottom;
- auto bottom = buffer->height - rect.top;
+ auto top = height - rect.bottom;
+ auto bottom = height - rect.top;
Rect flippedRect{rect.left, top, rect.right, bottom};
flippedRegion.orSelf(flippedRect);
}
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index ff58420..4ef9a69 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -299,7 +299,7 @@
ASSERT_NO_FATAL_FAILURE(ConnectProducer());
// One past the end of the last 'query' enum value. Update this if we add more enums.
- const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_DEFAULT_DATASPACE + 1;
+ const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
int value;
// What was out of range
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index d750cd0..1a50b24 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -27,6 +27,9 @@
#include <utils/Log.h>
#include <utils/Thread.h>
+EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+#define CROP_EXT_STR "EGL_ANDROID_image_crop"
+
namespace android {
class SurfaceTextureClientTest : public ::testing::Test {
@@ -615,6 +618,18 @@
}
TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
+ // Query to see if the image crop extension exists
+ EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS);
+ size_t cropExtLen = strlen(CROP_EXT_STR);
+ size_t extsLen = strlen(exts);
+ bool equal = !strcmp(CROP_EXT_STR, exts);
+ bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1);
+ bool atEnd = (cropExtLen+1) < extsLen &&
+ !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1));
+ bool inMiddle = strstr(exts, " " CROP_EXT_STR " ");
+ bool hasEglAndroidImageCrop = equal || atStart || atEnd || inMiddle;
+
android_native_buffer_t* buf[3];
float mtx[16] = {};
android_native_rect_t crop;
@@ -633,15 +648,17 @@
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
mST->getTransformMatrix(mtx);
- // This accounts for the .5 texel shrink for each edge that's included in the
- // transform matrix to avoid texturing outside the crop region.
- EXPECT_EQ(0.5, mtx[0]);
+ // If the egl image crop extension is not present, this accounts for the
+ // .5 texel shrink for each edge that's included in the transform matrix
+ // to avoid texturing outside the crop region. Otherwise the crop is not
+ // included in the transform matrix.
+ EXPECT_EQ(hasEglAndroidImageCrop ? 1 : 0.5, mtx[0]);
EXPECT_EQ(0.f, mtx[1]);
EXPECT_EQ(0.f, mtx[2]);
EXPECT_EQ(0.f, mtx[3]);
EXPECT_EQ(0.f, mtx[4]);
- EXPECT_EQ(-0.5, mtx[5]);
+ EXPECT_EQ(hasEglAndroidImageCrop ? -1 : -0.5, mtx[5]);
EXPECT_EQ(0.f, mtx[6]);
EXPECT_EQ(0.f, mtx[7]);
@@ -650,8 +667,8 @@
EXPECT_EQ(1.f, mtx[10]);
EXPECT_EQ(0.f, mtx[11]);
- EXPECT_EQ(0.0625f, mtx[12]);
- EXPECT_EQ(0.5625f, mtx[13]);
+ EXPECT_EQ(hasEglAndroidImageCrop ? 0 : 0.0625f, mtx[12]);
+ EXPECT_EQ(hasEglAndroidImageCrop ? 1 : 0.5625f, mtx[13]);
EXPECT_EQ(0.f, mtx[14]);
EXPECT_EQ(1.f, mtx[15]);
}
diff --git a/libs/gui/tests/SurfaceTextureGLToGL_test.cpp b/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
index f4c7961..6edbfb8 100644
--- a/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
@@ -188,10 +188,10 @@
// This test should have the only reference to buffer 0.
EXPECT_EQ(1, buffers[0]->getStrongCount());
- // The GLConsumer should hold a single reference to buffer 1 in its
- // mCurrentBuffer member. All of the references in the slots should have
- // been released.
- EXPECT_EQ(2, buffers[1]->getStrongCount());
+ // The GLConsumer should hold one reference to buffer 1 in its
+ // mCurrentTextureImage member and another reference in mEglSlots. The third
+ // reference is in this test.
+ EXPECT_EQ(3, buffers[1]->getStrongCount());
}
TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
@@ -235,14 +235,19 @@
ASSERT_EQ(EGL_SUCCESS, eglGetError());
mProducerEglSurface = EGL_NO_SURFACE;
- EXPECT_EQ(1, buffers[0]->getStrongCount());
EXPECT_EQ(1, buffers[1]->getStrongCount());
// Depending on how lazily the GL driver dequeues buffers, we may end up
- // with either two or three total buffers. If there are three, make sure
- // the last one was properly down-ref'd.
+ // with either two or three total buffers. If there are three, each entry
+ // of the buffers array will be unique and there should only be one
+ // reference (the one in this test). If there are two the first and last
+ // element in the array will be equal meaning that buffer representing both
+ // 0 and 2 will have two references (one for 0 and one for 2).
if (buffers[2] != buffers[0]) {
+ EXPECT_EQ(1, buffers[0]->getStrongCount());
EXPECT_EQ(1, buffers[2]->getStrongCount());
+ } else {
+ EXPECT_EQ(2, buffers[0]->getStrongCount());
}
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 85e9675..9b265af 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -104,6 +104,9 @@
// we have a h/w allocator and h/w buffer is requested
status_t err;
+ // Filter out any usage bits that should not be passed to the gralloc module
+ usage &= GRALLOC_USAGE_ALLOC_MASK;
+
int outStride = 0;
err = mAllocDev->alloc(mAllocDev, static_cast<int>(width),
static_cast<int>(height), format, static_cast<int>(usage), handle,
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 1feac8b..593d0c2 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -394,7 +394,13 @@
depth.width = width;
depth.height = height;
depth.stride = depth.width; // use the width here
- depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ uint64_t allocSize = static_cast<uint64_t>(depth.stride) *
+ static_cast<uint64_t>(depth.height) * 2;
+ if (depth.stride < 0 || depth.height > INT_MAX ||
+ allocSize > UINT32_MAX) {
+ return setError(EGL_BAD_ALLOC, EGL_FALSE);
+ }
+ depth.data = (GGLubyte*)malloc(allocSize);
if (depth.data == 0) {
return setError(EGL_BAD_ALLOC, EGL_FALSE);
}
@@ -548,7 +554,14 @@
depth.width = width;
depth.height = height;
depth.stride = buffer->stride;
- depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ uint64_t allocSize = static_cast<uint64_t>(depth.stride) *
+ static_cast<uint64_t>(depth.height) * 2;
+ if (depth.stride < 0 || depth.height > INT_MAX ||
+ allocSize > UINT32_MAX) {
+ setError(EGL_BAD_ALLOC, EGL_FALSE);
+ return EGL_FALSE;
+ }
+ depth.data = (GGLubyte*)malloc(allocSize);
if (depth.data == 0) {
setError(EGL_BAD_ALLOC, EGL_FALSE);
return EGL_FALSE;
@@ -666,7 +679,14 @@
depth.width = pixmap->width;
depth.height = pixmap->height;
depth.stride = depth.width; // use the width here
- depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ uint64_t allocSize = static_cast<uint64_t>(depth.stride) *
+ static_cast<uint64_t>(depth.height) * 2;
+ if (depth.stride < 0 || depth.height > INT_MAX ||
+ allocSize > UINT32_MAX) {
+ setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return;
+ }
+ depth.data = (GGLubyte*)malloc(allocSize);
if (depth.data == 0) {
setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
@@ -746,7 +766,14 @@
depth.width = pbuffer.width;
depth.height = pbuffer.height;
depth.stride = depth.width; // use the width here
- depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ uint64_t allocSize = static_cast<uint64_t>(depth.stride) *
+ static_cast<uint64_t>(depth.height) * 2;
+ if (depth.stride < 0 || depth.height > INT_MAX ||
+ allocSize > UINT32_MAX) {
+ setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return;
+ }
+ depth.data = (GGLubyte*)malloc(allocSize);
if (depth.data == 0) {
setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
return;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 7c70fa0..4e0e5bc 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -292,6 +292,44 @@
return (const GLubyte *)c->gl_extensions.string();
}
+const GLubyte * egl_get_string_for_current_context(GLenum name, GLuint index) {
+ // NOTE: returning NULL here will fall-back to the default
+ // implementation.
+
+ EGLContext context = egl_tls_t::getContext();
+ if (context == EGL_NO_CONTEXT)
+ return NULL;
+
+ egl_context_t const * const c = get_context(context);
+ if (c == NULL) // this should never happen, by construction
+ return NULL;
+
+ if (name != GL_EXTENSIONS)
+ return NULL;
+
+ // if index is out of bounds, assume it will be in the default
+ // implementation too, so we don't have to generate a GL error here
+ if (index >= c->tokenized_gl_extensions.size())
+ return NULL;
+
+ return (const GLubyte *)c->tokenized_gl_extensions.itemAt(index).string();
+}
+
+GLint egl_get_num_extensions_for_current_context() {
+ // NOTE: returning -1 here will fall-back to the default
+ // implementation.
+
+ EGLContext context = egl_tls_t::getContext();
+ if (context == EGL_NO_CONTEXT)
+ return -1;
+
+ egl_context_t const * const c = get_context(context);
+ if (c == NULL) // this should never happen, by construction
+ return -1;
+
+ return (GLint)c->tokenized_gl_extensions.size();
+}
+
// ----------------------------------------------------------------------------
// this mutex protects:
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 8dd052c..5444631 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -562,15 +562,6 @@
return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t * const s = get_surface(surface);
- ANativeWindow* window = s->win.get();
- if (window) {
- int result = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
- if (result != OK) {
- ALOGE("eglDestroySurface: native_window_api_disconnect (win=%p) "
- "failed (%#x)",
- window, result);
- }
- }
EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
if (result == EGL_TRUE) {
_s.terminate();
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index d3ee76d..d511940 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -113,6 +113,18 @@
temp.append(gl_extensions);
gl_extensions.setTo(temp);
}
+
+ // tokenize the supported extensions for the glGetStringi() wrapper
+ exts = gl_extensions.string();
+ while (1) {
+ const char *end = strchr(exts, ' ');
+ if (end == NULL) {
+ tokenized_gl_extensions.push(String8(exts));
+ break;
+ }
+ tokenized_gl_extensions.push(String8(exts, end - exts));
+ exts = end + 1;
+ }
}
}
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 518fdec..f5a9f58 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -27,6 +27,7 @@
#include <utils/threads.h>
#include <utils/String8.h>
+#include <utils/Vector.h>
#include <system/window.h>
@@ -159,6 +160,7 @@
egl_connection_t const* cnx;
int version;
String8 gl_extensions;
+ Vector<String8> tokenized_gl_extensions;
};
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index d5dc012..6034a8e 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -205,13 +205,22 @@
#undef CALL_GL_API_RETURN
/*
- * glGetString() is special because we expose some extensions in the wrapper
+ * glGetString() and glGetStringi() are special because we expose some
+ * extensions in the wrapper. Also, wrapping glGetXXX() is required because
+ * the value returned for GL_NUM_EXTENSIONS may have been altered by the
+ * injection of the additional extensions.
*/
-extern "C" const GLubyte * __glGetString(GLenum name);
+extern "C" {
+ const GLubyte * __glGetString(GLenum name);
+ const GLubyte * __glGetStringi(GLenum name, GLuint index);
+ void __glGetBooleanv(GLenum pname, GLboolean * data);
+ void __glGetFloatv(GLenum pname, GLfloat * data);
+ void __glGetIntegerv(GLenum pname, GLint * data);
+ void __glGetInteger64v(GLenum pname, GLint64 * data);
+}
-const GLubyte * glGetString(GLenum name)
-{
+const GLubyte * glGetString(GLenum name) {
const GLubyte * ret = egl_get_string_for_current_context(name);
if (ret == NULL) {
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
@@ -219,3 +228,64 @@
}
return ret;
}
+
+const GLubyte * glGetStringi(GLenum name, GLuint index) {
+ const GLubyte * ret = egl_get_string_for_current_context(name, index);
+ if (ret == NULL) {
+ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+ if(_c) ret = _c->glGetStringi(name, index);
+ }
+ return ret;
+}
+
+void glGetBooleanv(GLenum pname, GLboolean * data) {
+ if (pname == GL_NUM_EXTENSIONS) {
+ int num_exts = egl_get_num_extensions_for_current_context();
+ if (num_exts >= 0) {
+ *data = num_exts > 0 ? GL_TRUE : GL_FALSE;
+ return;
+ }
+ }
+
+ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+ if (_c) _c->glGetBooleanv(pname, data);
+}
+
+void glGetFloatv(GLenum pname, GLfloat * data) {
+ if (pname == GL_NUM_EXTENSIONS) {
+ int num_exts = egl_get_num_extensions_for_current_context();
+ if (num_exts >= 0) {
+ *data = (GLfloat)num_exts;
+ return;
+ }
+ }
+
+ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+ if (_c) _c->glGetFloatv(pname, data);
+}
+
+void glGetIntegerv(GLenum pname, GLint * data) {
+ if (pname == GL_NUM_EXTENSIONS) {
+ int num_exts = egl_get_num_extensions_for_current_context();
+ if (num_exts >= 0) {
+ *data = (GLint)num_exts;
+ return;
+ }
+ }
+
+ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+ if (_c) _c->glGetIntegerv(pname, data);
+}
+
+void glGetInteger64v(GLenum pname, GLint64 * data) {
+ if (pname == GL_NUM_EXTENSIONS) {
+ int num_exts = egl_get_num_extensions_for_current_context();
+ if (num_exts >= 0) {
+ *data = (GLint64)num_exts;
+ return;
+ }
+ }
+
+ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+ if (_c) _c->glGetInteger64v(pname, data);
+}
diff --git a/opengl/libs/GLES2/gl2_api.in b/opengl/libs/GLES2/gl2_api.in
index 8363960..09d8b00 100644
--- a/opengl/libs/GLES2/gl2_api.in
+++ b/opengl/libs/GLES2/gl2_api.in
@@ -172,7 +172,7 @@
GLint API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar * name) {
CALL_GL_API_RETURN(glGetAttribLocation, program, name);
}
-void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean * data) {
+void API_ENTRY(__glGetBooleanv)(GLenum pname, GLboolean * data) {
CALL_GL_API(glGetBooleanv, pname, data);
}
void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint * params) {
@@ -181,13 +181,13 @@
GLenum API_ENTRY(glGetError)(void) {
CALL_GL_API_RETURN(glGetError);
}
-void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat * data) {
+void API_ENTRY(__glGetFloatv)(GLenum pname, GLfloat * data) {
CALL_GL_API(glGetFloatv, pname, data);
}
void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint * params) {
CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
}
-void API_ENTRY(glGetIntegerv)(GLenum pname, GLint * data) {
+void API_ENTRY(__glGetIntegerv)(GLenum pname, GLint * data) {
CALL_GL_API(glGetIntegerv, pname, data);
}
void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint * params) {
@@ -604,7 +604,7 @@
void API_ENTRY(glClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
CALL_GL_API(glClearBufferfi, buffer, drawbuffer, depth, stencil);
}
-const GLubyte * API_ENTRY(glGetStringi)(GLenum name, GLuint index) {
+const GLubyte * API_ENTRY(__glGetStringi)(GLenum name, GLuint index) {
CALL_GL_API_RETURN(glGetStringi, name, index);
}
void API_ENTRY(glCopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
@@ -649,7 +649,7 @@
void API_ENTRY(glWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout) {
CALL_GL_API(glWaitSync, sync, flags, timeout);
}
-void API_ENTRY(glGetInteger64v)(GLenum pname, GLint64 * data) {
+void API_ENTRY(__glGetInteger64v)(GLenum pname, GLint64 * data) {
CALL_GL_API(glGetInteger64v, pname, data);
}
void API_ENTRY(glGetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values) {
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index cb0e908..c0990ec 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -30,6 +30,9 @@
// ----------------------------------------------------------------------------
EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name);
+EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name,
+ GLuint index);
+EGLAPI GLint egl_get_num_extensions_for_current_context();
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/opengl/tools/glgen2/glgen.py b/opengl/tools/glgen2/glgen.py
index ed6b451..9b30fd1 100755
--- a/opengl/tools/glgen2/glgen.py
+++ b/opengl/tools/glgen2/glgen.py
@@ -86,11 +86,25 @@
return ', '.join(['"%s", %s' % (p[0], p[1]) for p in params])
-def overrideSymbolName(sym):
- # The wrapper intercepts glGetString and (sometimes) calls the generated
- # __glGetString thunk which dispatches to the driver's glGetString
- if sym == 'glGetString':
- return '__glGetString'
+def overrideSymbolName(sym, apiname):
+ # The wrapper intercepts various glGet and glGetString functions and
+ # (sometimes) calls the generated thunk which dispatches to the
+ # driver's implementation
+ wrapped_get_syms = {
+ 'gles1' : [
+ 'glGetString'
+ ],
+ 'gles2' : [
+ 'glGetString',
+ 'glGetStringi',
+ 'glGetBooleanv',
+ 'glGetFloatv',
+ 'glGetIntegerv',
+ 'glGetInteger64v',
+ ],
+ }
+ if sym in wrapped_get_syms.get(apiname):
+ return '__' + sym
else:
return sym
@@ -115,8 +129,8 @@
print('%s API_ENTRY(%s)(%s) {\n'
' %s(%s%s%s);\n'
'}'
- % (rtype, overrideSymbolName(fname), fmtParams(params),
- call, fname,
+ % (rtype, overrideSymbolName(fname, self.genOpts.apiname),
+ fmtParams(params), call, fname,
', ' if len(params) > 0 else '',
fmtArgs(params)),
file=self.outFile)
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index 96efc34..67142b6 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -139,7 +139,7 @@
enum { MAX_RESYNC_SAMPLES = 32 };
enum { MIN_RESYNC_SAMPLES_FOR_UPDATE = 3 };
enum { NUM_PRESENT_SAMPLES = 8 };
- enum { MAX_RESYNC_SAMPLES_WITHOUT_PRESENT = 12 };
+ enum { MAX_RESYNC_SAMPLES_WITHOUT_PRESENT = 4 };
// mPeriod is the computed period of the modeled vsync events in
// nanoseconds.
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 579b39e..02c31ff 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -305,13 +305,16 @@
}
void HWComposer::hotplug(int disp, int connected) {
- if (disp == HWC_DISPLAY_PRIMARY || disp >= VIRTUAL_DISPLAY_ID_BASE) {
+ if (disp >= VIRTUAL_DISPLAY_ID_BASE) {
ALOGE("hotplug event received for invalid display: disp=%d connected=%d",
disp, connected);
return;
}
queryDisplayProperties(disp);
- mEventHandler.onHotplugReceived(disp, bool(connected));
+ // Do not teardown or recreate the primary display
+ if (disp != HWC_DISPLAY_PRIMARY) {
+ mEventHandler.onHotplugReceived(disp, bool(connected));
+ }
}
static float getDefaultDensity(uint32_t width, uint32_t height) {
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index 1adcd1f..0dab872 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -88,5 +88,9 @@
mColorMatrixEnabled = (mtx != identity);
}
+const mat4& Description::getColorMatrix() const {
+ return mColorMatrix;
+}
+
} /* namespace android */
diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h
index 43b835f..8a3447c 100644
--- a/services/surfaceflinger/RenderEngine/Description.h
+++ b/services/surfaceflinger/RenderEngine/Description.h
@@ -66,6 +66,7 @@
void setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
void setProjectionMatrix(const mat4& mtx);
void setColorMatrix(const mat4& mtx);
+ const mat4& getColorMatrix() const;
private:
bool mUniformsDirty;
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index 2e6af49..1a9f59b 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -262,14 +262,6 @@
}
}
-void GLES11RenderEngine::beginGroup(const mat4& /*colorTransform*/) {
- // doesn't do anything in GLES 1.1
-}
-
-void GLES11RenderEngine::endGroup() {
- // doesn't do anything in GLES 1.1
-}
-
void GLES11RenderEngine::dump(String8& result) {
RenderEngine::dump(result);
}
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 87eb3e4..08de646 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -62,9 +62,6 @@
virtual void drawMesh(const Mesh& mesh);
- virtual void beginGroup(const mat4& colorTransform);
- virtual void endGroup();
-
virtual size_t getMaxTextureSize() const;
virtual size_t getMaxViewportDims() const;
};
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 8712c9a..1fabaf5 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -169,6 +169,12 @@
mState.setTexture(texture);
}
+mat4 GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
+ mat4 oldTransform = mState.getColorMatrix();
+ mState.setColorMatrix(colorTransform);
+ return oldTransform;
+}
+
void GLES20RenderEngine::disableTexturing() {
mState.disableTexture();
}
@@ -237,78 +243,6 @@
}
}
-void GLES20RenderEngine::beginGroup(const mat4& colorTransform) {
-
- GLuint tname, name;
- // create the texture
- glGenTextures(1, &tname);
- glBindTexture(GL_TEXTURE_2D, tname);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mVpWidth, mVpHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- // create a Framebuffer Object to render into
- glGenFramebuffers(1, &name);
- glBindFramebuffer(GL_FRAMEBUFFER, name);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
-
- Group group;
- group.texture = tname;
- group.fbo = name;
- group.width = mVpWidth;
- group.height = mVpHeight;
- group.colorTransform = colorTransform;
-
- mGroupStack.push(group);
-}
-
-void GLES20RenderEngine::endGroup() {
-
- const Group group(mGroupStack.top());
- mGroupStack.pop();
-
- // activate the previous render target
- GLuint fbo = 0;
- if (!mGroupStack.isEmpty()) {
- fbo = mGroupStack.top().fbo;
- }
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- // set our state
- Texture texture(Texture::TEXTURE_2D, group.texture);
- texture.setDimensions(group.width, group.height);
- glBindTexture(GL_TEXTURE_2D, group.texture);
-
- mState.setPlaneAlpha(1.0f);
- mState.setPremultipliedAlpha(true);
- mState.setOpaque(false);
- mState.setTexture(texture);
- mState.setColorMatrix(group.colorTransform);
- glDisable(GL_BLEND);
-
- Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
- Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
- Mesh::VertexArray<vec2> texCoord(mesh.getTexCoordArray<vec2>());
- position[0] = vec2(0, 0);
- position[1] = vec2(group.width, 0);
- position[2] = vec2(group.width, group.height);
- position[3] = vec2(0, group.height);
- texCoord[0] = vec2(0, 0);
- texCoord[1] = vec2(1, 0);
- texCoord[2] = vec2(1, 1);
- texCoord[3] = vec2(0, 1);
- drawMesh(mesh);
-
- // reset color matrix
- mState.setColorMatrix(mat4());
-
- // free our fbo and texture
- glDeleteFramebuffers(1, &group.fbo);
- glDeleteTextures(1, &group.texture);
-}
-
void GLES20RenderEngine::dump(String8& result) {
RenderEngine::dump(result);
}
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 3d6243e..819356a 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -72,14 +72,12 @@
virtual void setupLayerTexturing(const Texture& texture);
virtual void setupLayerBlackedOut();
virtual void setupFillWithColor(float r, float g, float b, float a);
+ virtual mat4 setupColorTransform(const mat4& colorTransform);
virtual void disableTexturing();
virtual void disableBlending();
virtual void drawMesh(const Mesh& mesh);
- virtual void beginGroup(const mat4& colorTransform);
- virtual void endGroup();
-
virtual size_t getMaxTextureSize() const;
virtual size_t getMaxViewportDims() const;
};
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 8d7529c..31a961e 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -99,18 +99,16 @@
virtual void setupLayerBlackedOut() = 0;
virtual void setupFillWithColor(float r, float g, float b, float a) = 0;
+ virtual mat4 setupColorTransform(const mat4& /* colorTransform */) {
+ return mat4();
+ }
+
virtual void disableTexturing() = 0;
virtual void disableBlending() = 0;
// drawing
virtual void drawMesh(const Mesh& mesh) = 0;
- // grouping
- // creates a color-transform group, everything drawn in the group will be
- // transformed by the given color transform when endGroup() is called.
- virtual void beginGroup(const mat4& colorTransform) = 0;
- virtual void endGroup() = 0;
-
// queries
virtual size_t getMaxTextureSize() const = 0;
virtual size_t getMaxViewportDims() const = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0d57ae5..1388ce8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1872,9 +1872,9 @@
if (mDaltonize) {
colorMatrix = colorMatrix * mDaltonizer();
}
- engine.beginGroup(colorMatrix);
+ mat4 oldMatrix = engine.setupColorTransform(colorMatrix);
doComposeSurfaces(hw, dirtyRegion);
- engine.endGroup();
+ engine.setupColorTransform(oldMatrix);
}
// update the swap region and clear the dirty region
@@ -3337,8 +3337,8 @@
sp<Surface> sur = new Surface(producer, false);
ANativeWindow* window = sur.get();
- status_t result = NO_ERROR;
- if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
+ status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
+ if (result == NO_ERROR) {
uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
@@ -3428,7 +3428,7 @@
result = BAD_VALUE;
}
// queueBuffer takes ownership of syncFd
- window->queueBuffer(window, buffer, syncFd);
+ result = window->queueBuffer(window, buffer, syncFd);
}
} else {
result = BAD_VALUE;
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 4d363c8..dcde512 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -16,6 +16,8 @@
#include <gtest/gtest.h>
+#include <android/native_window.h>
+
#include <binder/IMemory.h>
#include <gui/ISurfaceComposer.h>
@@ -53,21 +55,23 @@
class ScreenCapture : public RefBase {
public:
static void captureScreen(sp<ScreenCapture>* sc) {
- sp<IMemoryHeap> heap;
- uint32_t w=0, h=0;
- PixelFormat fmt=0;
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ IGraphicBufferProducer::QueueBufferOutput bufferOutput;
+ sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &heap, &w, &h, &fmt, 0, 0,
- 0, INT_MAX));
- ASSERT_TRUE(heap != NULL);
- ASSERT_EQ(PIXEL_FORMAT_RGBA_8888, fmt);
- *sc = new ScreenCapture(w, h, heap);
+ sp<IBinder> display(sf->getBuiltInDisplay(
+ ISurfaceComposer::eDisplayIdMain));
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 0, 0,
+ 0, INT_MAX, false));
+ *sc = new ScreenCapture(cpuConsumer);
}
void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) {
- const uint8_t* img = reinterpret_cast<const uint8_t*>(mHeap->base());
- const uint8_t* pixel = img + (4 * (y*mWidth + x));
+ ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mBuf.format);
+ const uint8_t* img = static_cast<const uint8_t*>(mBuf.data);
+ const uint8_t* pixel = img + (4 * (y * mBuf.stride + x));
if (r != pixel[0] || g != pixel[1] || b != pixel[2]) {
String8 err(String8::format("pixel @ (%3d, %3d): "
"expected [%3d, %3d, %3d], got [%3d, %3d, %3d]",
@@ -77,15 +81,17 @@
}
private:
- ScreenCapture(uint32_t w, uint32_t h, const sp<IMemoryHeap>& heap) :
- mWidth(w),
- mHeight(h),
- mHeap(heap)
- {}
+ ScreenCapture(const sp<CpuConsumer>& cc) :
+ mCC(cc) {
+ EXPECT_EQ(NO_ERROR, mCC->lockNextBuffer(&mBuf));
+ }
- const uint32_t mWidth;
- const uint32_t mHeight;
- sp<IMemoryHeap> mHeap;
+ ~ScreenCapture() {
+ mCC->unlockBuffer(mBuf);
+ }
+
+ sp<CpuConsumer> mCC;
+ CpuConsumer::LockedBuffer mBuf;
};
class LayerUpdateTest : public ::testing::Test {