Merge "OMX IL header additions for FLAC" into jb-dev
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 81b56c2..8b84951 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -51,6 +51,7 @@
PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'),
DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
+ SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index e7fac3d..1c80d0c 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -170,7 +170,6 @@
mFrameNumber(0),
mBuf(INVALID_BUFFER_SLOT) {
mCrop.makeInvalid();
- mActiveRect.makeInvalid();
}
// mGraphicBuffer points to the buffer allocated for this slot or is NULL
// if no buffer has been allocated.
@@ -194,11 +193,6 @@
// mBuf is the slot index of this buffer
int mBuf;
-
- // mActiveRect is the active rectangle for the buffer. Pixels outside
- // this rectangle are considered completely transparent for the purposes
- // of window composition.
- Rect mActiveRect;
};
// The following public functions is the consumer facing interface
@@ -302,7 +296,6 @@
mAcquireCalled(false),
mNeedsCleanupOnRelease(false) {
mCrop.makeInvalid();
- mActiveRect.makeInvalid();
}
// mGraphicBuffer points to the buffer allocated for this slot or is NULL
@@ -359,12 +352,6 @@
// mCrop is the current crop rectangle for this buffer slot.
Rect mCrop;
- // mActiveRect is the current active rectangle for this buffer slot.
- // Pixels outside of this rectangle are to be treated as completely
- // transparent during window composition. The rectangle is in buffer
- // pixel coordinates.
- Rect mActiveRect;
-
// mTransform is the current transform flags for this buffer slot.
uint32_t mTransform;
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index 7abc7db..1e33764 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -86,25 +86,21 @@
// QueueBufferInput must be a POD structure
struct QueueBufferInput {
inline QueueBufferInput(int64_t timestamp,
- const Rect& crop, int scalingMode, uint32_t transform,
- const Rect& activeRect)
+ const Rect& crop, int scalingMode, uint32_t transform)
: timestamp(timestamp), crop(crop), scalingMode(scalingMode),
- transform(transform), activeRect(activeRect) { }
+ transform(transform) { }
inline void deflate(int64_t* outTimestamp, Rect* outCrop,
- int* outScalingMode, uint32_t* outTransform,
- Rect* outActiveRect) const {
+ int* outScalingMode, uint32_t* outTransform) const {
*outTimestamp = timestamp;
*outCrop = crop;
*outScalingMode = scalingMode;
*outTransform = transform;
- *outActiveRect = activeRect;
}
private:
int64_t timestamp;
Rect crop;
int scalingMode;
uint32_t transform;
- Rect activeRect;
};
// QueueBufferOutput must be a POD structure
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 7540ed8..f9cf0be 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -144,6 +144,10 @@
// updateTexImage() is called.
status_t setDefaultBufferSize(uint32_t width, uint32_t height);
+ // setFilteringEnabled sets whether the transform matrix should be computed
+ // for use with bilinear filtering.
+ void setFilteringEnabled(bool enabled);
+
// getCurrentBuffer returns the buffer associated with the current image.
sp<GraphicBuffer> getCurrentBuffer() const;
@@ -154,9 +158,6 @@
// getCurrentCrop returns the cropping rectangle of the current buffer.
Rect getCurrentCrop() const;
- // getCurrentActiveRect returns the active rectangle of the current buffer.
- Rect getCurrentActiveRect() const;
-
// getCurrentTransform returns the transform of the current buffer.
uint32_t getCurrentTransform() const;
@@ -273,12 +274,6 @@
// It gets set each time updateTexImage is called.
Rect mCurrentCrop;
- // mCurrentActiveRect is the active rectangle that applies to the current
- // texture. It gets set each time updateTexImage is called. All pixels
- // outside the active rectangle are be considered completely transparent for
- // the purpose of window composition.
- Rect mCurrentActiveRect;
-
// mCurrentTransform is the transform identifier for the current texture. It
// gets set each time updateTexImage is called.
uint32_t mCurrentTransform;
@@ -298,6 +293,11 @@
uint32_t mDefaultWidth, mDefaultHeight;
+ // mFilteringEnabled indicates whether the transform matrix is computed for
+ // use with bilinear filtering. It defaults to true and is changed by
+ // setFilteringEnabled().
+ bool mFilteringEnabled;
+
// mTexName is the name of the OpenGL texture to which streamed images will
// be bound when updateTexImage is called. It is set at construction time
// and can be changed with a call to attachToContext.
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index c4d4320..b11d572 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -80,10 +80,10 @@
int dispatchSetBuffersTransform(va_list args);
int dispatchSetBuffersTimestamp(va_list args);
int dispatchSetCrop(va_list args);
+ int dispatchSetPostTransformCrop(va_list args);
int dispatchSetUsage(va_list args);
int dispatchLock(va_list args);
int dispatchUnlockAndPost(va_list args);
- int dispatchSetActiveRect(va_list args);
protected:
virtual int cancelBuffer(ANativeWindowBuffer* buffer);
@@ -104,10 +104,10 @@
virtual int setBuffersTransform(int transform);
virtual int setBuffersTimestamp(int64_t timestamp);
virtual int setCrop(Rect const* rect);
+ virtual int setPostTransformCrop(Rect const* rect);
virtual int setUsage(uint32_t reqUsage);
virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
virtual int unlockAndPost();
- virtual int setActiveRect(Rect const* rect);
enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
@@ -159,6 +159,13 @@
// that gets queued. It is set by calling setCrop.
Rect mCrop;
+ // mCropNeedsTransform indicates whether mCrop is in post-transform
+ // coordinates and must be transformed using the inverse of mTransform
+ // before being queued with a buffer. Otherwise the crop is passed
+ // untransformed. It is initialized to false, is set to true by
+ // setPostTransformCrop, and set to false by setCrop.
+ bool mCropNeedsTransform;
+
// mScalingMode is the scaling mode that will be used for the next
// buffers that get queued. It is set by calling setScalingMode.
int mScalingMode;
@@ -167,10 +174,6 @@
// buffer that gets queued. It is set by calling setTransform.
uint32_t mTransform;
- // mActiveRect is the active rectangle that will be used for the next buffer
- // that gets queued. It is set by calling setActiveRect.
- Rect mActiveRect;
-
// mDefaultWidth is default width of the buffers, regardless of the
// native_window_set_buffers_dimensions call.
uint32_t mDefaultWidth;
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 9e98bc5..bd82061 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -136,10 +136,18 @@
void translate(int32_t dx, int32_t dy) { // legacy, don't use.
offsetBy(dx, dy);
}
-
+
Rect& offsetTo(int32_t x, int32_t y);
Rect& offsetBy(int32_t x, int32_t y);
bool intersect(const Rect& with, Rect* result) const;
+
+ // Create a new Rect by transforming this one using a graphics HAL
+ // transform. This rectangle is defined in a coordinate space starting at
+ // the origin and extending to (width, height). If the transform includes
+ // a ROT90 then the output rectangle is defined in a space extending to
+ // (height, width). Otherwise the output rectangle is in the same space as
+ // the input.
+ Rect transform(uint32_t xform, int32_t width, int32_t height);
};
ANDROID_BASIC_TYPES_TRAITS(Rect)
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
index 6e2e284..984cd46 100644
--- a/include/utils/Trace.h
+++ b/include/utils/Trace.h
@@ -48,7 +48,9 @@
#define ATRACE_TAG_WEBVIEW (1<<4)
#define ATRACE_TAG_WINDOW_MANAGER (1<<5)
#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6)
-#define ATRACE_TAG_LAST ATRACE_TAG_ACTIVITY_MANAGER
+#define ATRACE_TAG_SYNC_MANAGER (1<<7)
+#define ATRACE_TAG_AUDIO (1<<8)
+#define ATRACE_TAG_LAST ATRACE_TAG_AUDIO
#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)
@@ -119,11 +121,16 @@
}
}
+ static void changeCallback();
+
// init opens the trace marker file for writing and reads the
// atrace.tags.enableflags system property. It does this only the first
// time it is run, using sMutex for synchronization.
static void init();
+ // retrieve the current value of the system property.
+ static void loadSystemProperty();
+
// sIsReady is a boolean value indicating whether a call to init() has
// completed in this process. It is initialized to 0 and set to 1 when the
// first init() call completes. It is set to 1 even if a failure occurred
diff --git a/include/utils/misc.h b/include/utils/misc.h
index 23f2a4c..d7d5bc1 100644
--- a/include/utils/misc.h
+++ b/include/utils/misc.h
@@ -88,6 +88,10 @@
void k_itoa(int value, char* str, int base);
char* itoa(int val, int base);
+typedef void (*sysprop_change_callback)(void);
+void add_sysprop_change_callback(sysprop_change_callback cb, int priority);
+void report_sysprop_change();
+
}; // namespace android
#endif // _LIBS_UTILS_MISC_H
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index e20d8a3..1f21f9c 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -17,6 +17,7 @@
#include <binder/Binder.h>
#include <utils/Atomic.h>
+#include <utils/misc.h>
#include <binder/BpBinder.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
@@ -199,6 +200,12 @@
}
return dump(fd, args);
}
+
+ case SYSPROPS_TRANSACTION: {
+ report_sysprop_change();
+ return NO_ERROR;
+ }
+
default:
return UNKNOWN_TRANSACTION;
}
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index 355a319..cf44bb9 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -140,8 +140,7 @@
ssize_t size = tube->write(vaddr, objSize);
if (size < 0) {
// error occurred
- numObjects = -size;
- break;
+ return size;
} else if (size == 0) {
// no more space
break;
@@ -160,8 +159,7 @@
ssize_t size = tube->read(vaddr, objSize);
if (size < 0) {
// error occurred
- numObjects = -size;
- break;
+ return size;
} else if (size == 0) {
// no more messages
break;
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 5095ebd..e53162b 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -540,15 +540,11 @@
uint32_t transform;
int scalingMode;
int64_t timestamp;
- Rect activeRect;
- input.deflate(×tamp, &crop, &scalingMode, &transform,
- &activeRect);
+ input.deflate(×tamp, &crop, &scalingMode, &transform);
- ST_LOGV("queueBuffer: slot=%d time=%lld crop=[%d,%d,%d,%d] "
- "active=[%d,%d,%d,%d]", buf, timestamp, crop.left, crop.top,
- crop.right, crop.bottom, activeRect.left, activeRect.top,
- activeRect.right, activeRect.bottom);
+ ST_LOGV("queueBuffer: slot=%d time=%lld crop=[%d,%d,%d,%d]",
+ buf, timestamp, crop.left, crop.top, crop.right, crop.bottom);
sp<ConsumerListener> listener;
@@ -572,6 +568,16 @@
return -EINVAL;
}
+ const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
+ Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
+ Rect croppedCrop;
+ crop.intersect(bufferRect, &croppedCrop);
+ if (croppedCrop != crop) {
+ ST_LOGE("queueBuffer: crop rect is not contained within the "
+ "buffer in slot %d", buf);
+ return -EINVAL;
+ }
+
if (mSynchronousMode) {
// In synchronous mode we queue all buffers in a FIFO.
mQueue.push_back(buf);
@@ -600,12 +606,12 @@
mSlots[buf].mTimestamp = timestamp;
mSlots[buf].mCrop = crop;
mSlots[buf].mTransform = transform;
- mSlots[buf].mActiveRect = activeRect;
switch (scalingMode) {
case NATIVE_WINDOW_SCALING_MODE_FREEZE:
case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
+ case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
break;
default:
ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
@@ -859,7 +865,6 @@
buffer->mFrameNumber = mSlots[buf].mFrameNumber;
buffer->mTimestamp = mSlots[buf].mTimestamp;
buffer->mBuf = buf;
- buffer->mActiveRect = mSlots[buf].mActiveRect;
mSlots[buf].mAcquireCalled = true;
mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index f9a2c04..5cc76b4 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -40,6 +40,7 @@
{
mName = hwSensor->name;
mVendor = hwSensor->vendor;
+ mVersion = hwSensor->version;
mHandle = hwSensor->handle;
mType = hwSensor->type;
mMinValue = 0; // FIXME: minValue
@@ -101,7 +102,7 @@
{
return sizeof(int32_t) + ((mName.length() + 3) & ~3) +
sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
- sizeof(int32_t) * 2 +
+ sizeof(int32_t) * 3 +
sizeof(float) * 4 +
sizeof(int32_t);
}
@@ -140,6 +141,7 @@
offset += write(buffer, offset, mName);
offset += write(buffer, offset, int32_t(mVendor.length()));
offset += write(buffer, offset, mVendor);
+ offset += write(buffer, offset, mVersion);
offset += write(buffer, offset, mHandle);
offset += write(buffer, offset, mType);
offset += write(buffer, offset, mMinValue);
@@ -178,6 +180,7 @@
offset += read(buffer, offset, &mName, len);
offset += read(buffer, offset, &len);
offset += read(buffer, offset, &mVendor, len);
+ offset += read(buffer, offset, &mVersion);
offset += read(buffer, offset, &mHandle);
offset += read(buffer, offset, &mType);
offset += read(buffer, offset, &mMinValue);
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 04ba640..8a1bf41 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -79,14 +79,21 @@
const int fd = getFd();
sp<Looper> looper(getLooper());
+ int events;
int32_t result;
do {
- result = looper->pollOnce(-1);
- if (result == ALOOPER_EVENT_ERROR) {
+ result = looper->pollOnce(-1, NULL, &events, NULL);
+ if (result == ALOOPER_POLL_ERROR) {
ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
result = -EPIPE; // unknown error, so we make up one
break;
}
+ if (events & ALOOPER_EVENT_HANGUP) {
+ // the other-side has died
+ ALOGE("SensorEventQueue::waitForEvent error HANGUP");
+ result = -EPIPE; // unknown error, so we make up one
+ break;
+ }
} while (result != fd);
return (result == fd) ? status_t(NO_ERROR) : result;
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index c103e14..1e58a21 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -108,6 +108,7 @@
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
mCurrentTransform(0),
mCurrentTimestamp(0),
+ mFilteringEnabled(true),
mTexName(tex),
#ifdef USE_FENCE_SYNC
mUseFenceSync(useFenceSync),
@@ -294,7 +295,6 @@
mCurrentTransform = item.mTransform;
mCurrentScalingMode = item.mScalingMode;
mCurrentTimestamp = item.mTimestamp;
- mCurrentActiveRect = item.mActiveRect;
computeCurrentTransformMatrix();
} else {
if (err < 0) {
@@ -352,7 +352,7 @@
// new EGLDisplay).
for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
EGLImageKHR img = mEGLSlots[i].mEglImage;
- if (img != EGL_NO_IMAGE_KHR && i != mCurrentTexture) {
+ if (img != EGL_NO_IMAGE_KHR) {
eglDestroyImageKHR(mEglDisplay, img);
mEGLSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
}
@@ -399,21 +399,12 @@
glBindTexture(mTexTarget, tex);
if (mCurrentTextureBuf != NULL) {
- // If the current buffer is no longer associated with a slot, then it
- // doesn't have an EGLImage. In that case we create one now, but we also
- // destroy it once we've used it to attach the buffer to the OpenGL ES
- // texture.
- bool imageNeedsDestroy = false;
- EGLImageKHR image = EGL_NO_IMAGE_KHR;
- if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- image = mEGLSlots[mCurrentTexture].mEglImage;
- imageNeedsDestroy = false;
- } else {
- image = createImage(dpy, mCurrentTextureBuf);
- if (image == EGL_NO_IMAGE_KHR) {
- return UNKNOWN_ERROR;
- }
- imageNeedsDestroy = true;
+ // The EGLImageKHR that was associated with the slot was destroyed when
+ // the SurfaceTexture was detached from the old context, so we need to
+ // recreate it here.
+ EGLImageKHR image = createImage(dpy, mCurrentTextureBuf);
+ if (image == EGL_NO_IMAGE_KHR) {
+ return UNKNOWN_ERROR;
}
// Attach the current buffer to the GL texture.
@@ -427,9 +418,12 @@
err = UNKNOWN_ERROR;
}
- if (imageNeedsDestroy) {
- eglDestroyImageKHR(dpy, image);
- }
+ // We destroy the EGLImageKHR here because the current buffer may no
+ // longer be associated with one of the buffer slots, so we have
+ // nowhere to to store it. If the buffer is still associated with a
+ // slot then another EGLImageKHR will be created next time that buffer
+ // gets acquired in updateTexImage.
+ eglDestroyImageKHR(dpy, image);
if (err != OK) {
return err;
@@ -510,6 +504,15 @@
memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
}
+void SurfaceTexture::setFilteringEnabled(bool enabled) {
+ Mutex::Autolock lock(mMutex);
+ bool needsRecompute = mFilteringEnabled != enabled;
+ mFilteringEnabled = enabled;
+ if (needsRecompute) {
+ computeCurrentTransformMatrix();
+ }
+}
+
void SurfaceTexture::computeCurrentTransformMatrix() {
ST_LOGV("computeCurrentTransformMatrix");
@@ -540,37 +543,50 @@
}
sp<GraphicBuffer>& buf(mCurrentTextureBuf);
- float tx, ty, sx, sy;
- if (!mCurrentCrop.isEmpty()) {
- // In order to prevent bilinear sampling at the of the crop rectangle we
- // may need to shrink it by 2 texels in each direction. Normally this
- // would just need to take 1/2 a texel off each end, but because the
- // chroma channels will likely be subsampled we need to chop off a whole
- // texel. This will cause artifacts if someone does nearest sampling
- // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
- // accomodate the bilinear and nearest sampling uses.
- //
- // If nearest sampling turns out to be a desirable usage of these
- // textures then we could add the ability to switch a SurfaceTexture to
- // nearest-mode. Preferably, however, the image producers (video
- // decoder, camera, etc.) would simply not use a crop rectangle (or at
- // least not tell the framework about it) so that the GPU can do the
- // correct edge behavior.
- const float shrinkAmount = 1.0f; // the amount that each edge is shrunk
+ Rect cropRect = mCurrentCrop;
+ float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f;
+ float bufferWidth = buf->getWidth();
+ float bufferHeight = buf->getHeight();
+ if (!cropRect.isEmpty()) {
+ float shrinkAmount = 0.0f;
+ if (mFilteringEnabled) {
+ // In order to prevent bilinear sampling beyond the edge of the
+ // crop rectangle we may need to shrink it by 2 texels in each
+ // dimension. Normally this would just need to take 1/2 a texel
+ // off each end, but because the chroma channels of YUV420 images
+ // are subsampled we may need to shrink the crop region by a whole
+ // texel on each side.
+ switch (buf->getPixelFormat()) {
+ case PIXEL_FORMAT_RGBA_8888:
+ case PIXEL_FORMAT_RGBX_8888:
+ case PIXEL_FORMAT_RGB_888:
+ case PIXEL_FORMAT_RGB_565:
+ case PIXEL_FORMAT_BGRA_8888:
+ case PIXEL_FORMAT_RGBA_5551:
+ case PIXEL_FORMAT_RGBA_4444:
+ // We know there's no subsampling of any channels, so we
+ // only need to shrink by a half a pixel.
+ shrinkAmount = 0.5;
- tx = (float(mCurrentCrop.left) + shrinkAmount) /
- float(buf->getWidth());
- ty = (float(buf->getHeight() - mCurrentCrop.bottom) +
- shrinkAmount) / float(buf->getHeight());
- sx = (float(mCurrentCrop.width()) - (2.0f * shrinkAmount)) /
- float(buf->getWidth());
- sy = (float(mCurrentCrop.height()) - (2.0f * shrinkAmount)) /
- float(buf->getHeight());
- } else {
- tx = 0.0f;
- ty = 0.0f;
- sx = 1.0f;
- sy = 1.0f;
+ default:
+ // If we don't recognize the format, we must assume the
+ // worst case (that we care about), which is YUV420.
+ shrinkAmount = 1.0;
+ }
+ }
+
+ // Only shrink the dimensions that are not the size of the buffer.
+ if (cropRect.width() < bufferWidth) {
+ tx = (float(cropRect.left) + shrinkAmount) / bufferWidth;
+ sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) /
+ bufferWidth;
+ }
+ if (cropRect.height() < bufferHeight) {
+ ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) /
+ bufferHeight;
+ sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) /
+ bufferHeight;
+ }
}
float crop[16] = {
sx, 0, 0, 0,
@@ -659,11 +675,6 @@
return outCrop;
}
-Rect SurfaceTexture::getCurrentActiveRect() const {
- Mutex::Autolock lock(mMutex);
- return mCurrentActiveRect;
-}
-
uint32_t SurfaceTexture::getCurrentTransform() const {
Mutex::Autolock lock(mMutex);
return mCurrentTransform;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index fdd14c8..9c3e28d 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -76,9 +76,9 @@
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mCrop.clear();
+ mCropNeedsTransform = false;
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
- mActiveRect.clear();
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
@@ -238,9 +238,29 @@
return i;
}
+ Rect crop(mCrop);
+ if (mCropNeedsTransform) {
+ // The crop rect was specified in the post-transform coordinate space,
+ // so we need to transform that rect by the inverse of mTransform to
+ // put it into the buffer pixel space before queuing it.
+ uint32_t invTransform = mTransform;
+ int32_t width = buffer->width;
+ int32_t height = buffer->height;
+ if (mTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+ NATIVE_WINDOW_TRANSFORM_FLIP_H;
+ width = buffer->height;
+ height = buffer->width;
+ }
+ crop = mCrop.transform(invTransform, width, height);
+ }
+
+ // Make sure the crop rectangle is entirely inside the buffer.
+ crop.intersect(Rect(buffer->width, buffer->height), &crop);
+
ISurfaceTexture::QueueBufferOutput output;
- ISurfaceTexture::QueueBufferInput input(timestamp,
- mCrop, mScalingMode, mTransform, mActiveRect);
+ ISurfaceTexture::QueueBufferInput input(timestamp, crop, mScalingMode,
+ mTransform);
status_t err = mSurfaceTexture->queueBuffer(i, input, &output);
if (err != OK) {
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
@@ -321,6 +341,9 @@
case NATIVE_WINDOW_SET_CROP:
res = dispatchSetCrop(args);
break;
+ case NATIVE_WINDOW_SET_POST_TRANSFORM_CROP:
+ res = dispatchSetPostTransformCrop(args);
+ break;
case NATIVE_WINDOW_SET_BUFFER_COUNT:
res = dispatchSetBufferCount(args);
break;
@@ -357,9 +380,6 @@
case NATIVE_WINDOW_API_DISCONNECT:
res = dispatchDisconnect(args);
break;
- case NATIVE_WINDOW_SET_ACTIVE_RECT:
- res = dispatchSetActiveRect(args);
- break;
default:
res = NAME_NOT_FOUND;
break;
@@ -387,6 +407,11 @@
return setCrop(reinterpret_cast<Rect const*>(rect));
}
+int SurfaceTextureClient::dispatchSetPostTransformCrop(va_list args) {
+ android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
+ return setPostTransformCrop(reinterpret_cast<Rect const*>(rect));
+}
+
int SurfaceTextureClient::dispatchSetBufferCount(va_list args) {
size_t bufferCount = va_arg(args, size_t);
return setBufferCount(bufferCount);
@@ -430,11 +455,6 @@
return setBuffersTransform(transform);
}
-int SurfaceTextureClient::dispatchSetActiveRect(va_list args) {
- android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
- return setActiveRect(reinterpret_cast<Rect const*>(rect));
-}
-
int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) {
int64_t timestamp = va_arg(args, int64_t);
return setBuffersTimestamp(timestamp);
@@ -481,6 +501,7 @@
mReqHeight = 0;
mReqUsage = 0;
mCrop.clear();
+ mCropNeedsTransform = false;
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
if (api == NATIVE_WINDOW_API_CPU) {
@@ -512,6 +533,25 @@
Mutex::Autolock lock(mMutex);
mCrop = realRect;
+ mCropNeedsTransform = false;
+ return NO_ERROR;
+}
+
+int SurfaceTextureClient::setPostTransformCrop(Rect const* rect)
+{
+ ATRACE_CALL();
+ ALOGV("SurfaceTextureClient::setPostTransformCrop");
+
+ Rect realRect;
+ if (rect == NULL || rect->isEmpty()) {
+ realRect.clear();
+ } else {
+ realRect = *rect;
+ }
+
+ Mutex::Autolock lock(mMutex);
+ mCrop = realRect;
+ mCropNeedsTransform = true;
return NO_ERROR;
}
@@ -546,7 +586,6 @@
Mutex::Autolock lock(mMutex);
mReqWidth = w;
mReqHeight = h;
- mCrop.clear();
return NO_ERROR;
}
@@ -564,7 +603,6 @@
Mutex::Autolock lock(mMutex);
mUserWidth = w;
mUserHeight = h;
- mCrop.clear();
return NO_ERROR;
}
@@ -589,6 +627,7 @@
case NATIVE_WINDOW_SCALING_MODE_FREEZE:
case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
+ case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
break;
default:
ALOGE("unknown scaling mode: %d", mode);
@@ -609,23 +648,6 @@
return NO_ERROR;
}
-int SurfaceTextureClient::setActiveRect(Rect const* rect)
-{
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::setActiveRect");
-
- Rect realRect;
- if (rect == NULL || rect->isEmpty()) {
- realRect.clear();
- } else {
- realRect = *rect;
- }
-
- Mutex::Autolock lock(mMutex);
- mActiveRect = realRect;
- return NO_ERROR;
-}
-
int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
{
ALOGV("SurfaceTextureClient::setBuffersTimestamp");
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index b576ca5..8546fb9 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -20,6 +20,7 @@
#include <EGL/egl.h>
#include <gtest/gtest.h>
#include <gui/SurfaceTextureClient.h>
+#include <system/graphics.h>
#include <utils/Log.h>
#include <utils/Thread.h>
@@ -441,6 +442,68 @@
ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
}
+TEST_F(SurfaceTextureClientTest, SetPostTransformCropUntransforms) {
+ android_native_rect_t rect = {1, 5, 4, 14};
+ native_window_set_post_transform_crop(mANW.get(), &rect);
+
+ uint32_t xforms[] = {
+ HAL_TRANSFORM_FLIP_H,
+ HAL_TRANSFORM_FLIP_V,
+ HAL_TRANSFORM_ROT_90,
+ HAL_TRANSFORM_ROT_180,
+ HAL_TRANSFORM_ROT_270,
+ };
+
+ Rect expectedRects[] = {
+ Rect(4, 5, 7, 14), // HAL_TRANSFORM_FLIP_H
+ Rect(1, 2, 4, 11), // HAL_TRANSFORM_FLIP_V
+ Rect(5, 4, 14, 7), // HAL_TRANSFORM_ROT_90
+ Rect(4, 2, 7, 11), // HAL_TRANSFORM_ROT_180
+ Rect(2, 1, 11, 4), // HAL_TRANSFORM_ROT_270
+ };
+
+ for (size_t i = 0; i < sizeof(xforms)/sizeof(xforms[0]); i++) {
+ SCOPED_TRACE(String8::format("xform=%#x", xforms[i]).string());
+
+ int w = 8, h = 16;
+ if (xforms[i] & HAL_TRANSFORM_ROT_90) {
+ w = 16;
+ h = 8;
+ }
+ ASSERT_EQ(OK, native_window_set_buffers_transform(mANW.get(), xforms[i]));
+ ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), w, h));
+
+ android_native_buffer_t* buf;
+ ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
+ ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf));
+ ASSERT_EQ(OK, mST->updateTexImage());
+
+ Rect crop = mST->getCurrentCrop();
+ EXPECT_EQ(expectedRects[i].left, crop.left);
+ EXPECT_EQ(expectedRects[i].top, crop.top);
+ EXPECT_EQ(expectedRects[i].right, crop.right);
+ EXPECT_EQ(expectedRects[i].bottom, crop.bottom);
+ }
+}
+
+TEST_F(SurfaceTextureClientTest, SetCropCropsCrop) {
+ android_native_rect_t rect = {-2, -13, 40, 18};
+ native_window_set_crop(mANW.get(), &rect);
+
+ ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 4, 4));
+
+ android_native_buffer_t* buf;
+ ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
+ ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf));
+ ASSERT_EQ(OK, mST->updateTexImage());
+
+ Rect crop = mST->getCurrentCrop();
+ EXPECT_EQ(0, crop.left);
+ EXPECT_EQ(0, crop.top);
+ EXPECT_EQ(4, crop.right);
+ EXPECT_EQ(4, crop.bottom);
+}
+
// XXX: This is not expected to pass until the synchronization hacks are removed
// from the SurfaceTexture class.
TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index cff4476..d708f6d 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1262,28 +1262,6 @@
native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
}
-TEST_F(SurfaceTextureGLTest, GetCurrentActiveRectWorks) {
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
-
- ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
- NATIVE_WINDOW_API_CPU));
-
- ANativeWindowBuffer *anb;
-
- android_native_rect_t odd = {23, 78, 123, 477};
- ASSERT_EQ(OK, native_window_set_active_rect(mANW.get(), &odd));
- EXPECT_EQ (OK, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb));
- mFW->waitForFrame();
- EXPECT_EQ(OK,mST->updateTexImage());
- Rect r = mST->getCurrentCrop();
- assertRectEq(Rect(23, 78, 123, 477), r);
-
- ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
- NATIVE_WINDOW_API_CPU));
-}
-
-
TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
class ProducerThread : public Thread {
public:
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index 5694e00..65fe5f9 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <system/graphics.h>
#include <ui/Rect.h>
namespace android {
@@ -92,4 +93,24 @@
return !(result->isEmpty());
}
+Rect Rect::transform(uint32_t xform, int32_t width, int32_t height) {
+ Rect result(*this);
+ if (xform & HAL_TRANSFORM_FLIP_H) {
+ result = Rect(width - result.right, result.top,
+ width - result.left, result.bottom);
+ }
+ if (xform & HAL_TRANSFORM_FLIP_V) {
+ result = Rect(result.left, height - result.bottom,
+ result.right, height - result.top);
+ }
+ if (xform & HAL_TRANSFORM_ROT_90) {
+ int left = height - result.bottom;
+ int top = result.left;
+ int right = height - result.top;
+ int bottom = result.right;
+ result = Rect(left, top, right, bottom);
+ }
+ return result;
+}
+
}; // namespace android
diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp
index f7d8abe..5cd5731 100644
--- a/libs/utils/Trace.cpp
+++ b/libs/utils/Trace.cpp
@@ -19,6 +19,7 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <utils/misc.h>
namespace android {
@@ -27,10 +28,19 @@
uint64_t Tracer::sEnabledTags = 0;
Mutex Tracer::sMutex;
+void Tracer::changeCallback() {
+ Mutex::Autolock lock(sMutex);
+ if (sIsReady && sTraceFD >= 0) {
+ loadSystemProperty();
+ }
+}
+
void Tracer::init() {
Mutex::Autolock lock(sMutex);
if (!sIsReady) {
+ add_sysprop_change_callback(changeCallback, 0);
+
const char* const traceFileName =
"/sys/kernel/debug/tracing/trace_marker";
sTraceFD = open(traceFileName, O_WRONLY);
@@ -38,14 +48,18 @@
ALOGE("error opening trace file: %s (%d)", strerror(errno), errno);
// sEnabledTags remains zero indicating that no tracing can occur
} else {
- char value[PROPERTY_VALUE_MAX];
- property_get("atrace.tags.enableflags", value, "0");
- sEnabledTags = (strtoll(value, NULL, 0) & ATRACE_TAG_VALID_MASK)
- | ATRACE_TAG_ALWAYS;
+ loadSystemProperty();
}
android_atomic_release_store(1, &sIsReady);
}
}
+void Tracer::loadSystemProperty() {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.atrace.tags.enableflags", value, "0");
+ sEnabledTags = (strtoll(value, NULL, 0) & ATRACE_TAG_VALID_MASK)
+ | ATRACE_TAG_ALWAYS;
+}
+
} // namespace andoid
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
index dc89d15..b3c99e6 100644
--- a/libs/utils/misc.cpp
+++ b/libs/utils/misc.cpp
@@ -14,10 +14,13 @@
* limitations under the License.
*/
+#define LOG_TAG "misc"
+
//
// Miscellaneous utility functions.
//
#include <utils/misc.h>
+#include <utils/Log.h>
#include <sys/stat.h>
#include <string.h>
@@ -25,6 +28,12 @@
#include <assert.h>
#include <stdio.h>
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Vector.h>
+
using namespace android;
namespace android {
@@ -181,5 +190,54 @@
return val;
}
-}; // namespace android
+struct sysprop_change_callback_info {
+ sysprop_change_callback callback;
+ int priority;
+};
+#if defined(HAVE_PTHREADS)
+static pthread_mutex_t gSyspropMutex = PTHREAD_MUTEX_INITIALIZER;
+static Vector<sysprop_change_callback_info>* gSyspropList = NULL;
+#endif
+
+void add_sysprop_change_callback(sysprop_change_callback cb, int priority) {
+#if defined(HAVE_PTHREADS)
+ pthread_mutex_lock(&gSyspropMutex);
+ if (gSyspropList == NULL) {
+ gSyspropList = new Vector<sysprop_change_callback_info>();
+ }
+ sysprop_change_callback_info info;
+ info.callback = cb;
+ info.priority = priority;
+ bool added = false;
+ for (size_t i=0; i<gSyspropList->size(); i++) {
+ if (priority >= gSyspropList->itemAt(i).priority) {
+ gSyspropList->insertAt(info, i);
+ added = true;
+ break;
+ }
+ }
+ if (!added) {
+ gSyspropList->add(info);
+ }
+ pthread_mutex_unlock(&gSyspropMutex);
+#endif
+}
+
+void report_sysprop_change() {
+#if defined(HAVE_PTHREADS)
+ pthread_mutex_lock(&gSyspropMutex);
+ Vector<sysprop_change_callback_info> listeners;
+ if (gSyspropList != NULL) {
+ listeners = *gSyspropList;
+ }
+ pthread_mutex_unlock(&gSyspropMutex);
+
+ //ALOGI("Reporting sysprop change to %d listeners", listeners.size());
+ for (size_t i=0; i<listeners.size(); i++) {
+ listeners[i].callback();
+ }
+#endif
+}
+
+}; // namespace android
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 66bc64d..c5c2618 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -36,6 +36,10 @@
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_CFLAGS += -DEGL_TRACE=1
+ifeq ($(BOARD_ALLOW_EGL_HIBERNATION),true)
+ LOCAL_CFLAGS += -DBOARD_ALLOW_EGL_HIBERNATION
+endif
+
ifeq ($(TARGET_BOARD_PLATFORM),msm7k)
LOCAL_CFLAGS += -DADRENO130=1
endif
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index f2e3897..2cd1a93 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -420,7 +420,7 @@
if (mWakeCount == 0 && CC_UNLIKELY(mAttemptHibernation)) {
egl_connection_t* const cnx = &gEGLImpl;
mAttemptHibernation = false;
- if (mDpyValid &&
+ if (mAllowHibernation && mDpyValid &&
cnx->egl.eglHibernateProcessIMG &&
cnx->egl.eglAwakenProcessIMG) {
ALOGV("Hibernating\n");
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 412568b..7bb09a3 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -155,7 +155,12 @@
};
HibernationMachine(): mWakeCount(0), mHibernating(false),
- mAttemptHibernation(false), mDpyValid(false)
+ mAttemptHibernation(false), mDpyValid(false),
+#if BOARD_ALLOW_EGL_HIBERNATION
+ mAllowHibernation(true)
+#else
+ mAllowHibernation(false)
+#endif
{}
~HibernationMachine() {}
@@ -165,11 +170,12 @@
void setDisplayValid(bool valid);
private:
- Mutex mLock;
- int32_t mWakeCount;
- bool mHibernating;
- bool mAttemptHibernation;
- bool mDpyValid;
+ Mutex mLock;
+ int32_t mWakeCount;
+ bool mHibernating;
+ bool mAttemptHibernation;
+ bool mDpyValid;
+ const bool mAllowHibernation;
};
HibernationMachine mHibernation;
};
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e15e733..e936188 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -141,6 +141,47 @@
void Layer::validateVisibility(const Transform& globalTransform) {
LayerBase::validateVisibility(globalTransform);
+ if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
+ !mCurrentCrop.isEmpty()) {
+ // We need to shrink the window size to match the buffer crop
+ // rectangle.
+ const Layer::State& s(drawingState());
+ const Transform tr(globalTransform * s.transform);
+ float windowWidth = s.w;
+ float windowHeight = s.h;
+ float bufferWidth = mActiveBuffer->getWidth();
+ float bufferHeight = mActiveBuffer->getHeight();
+ if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ float tmp = bufferWidth;
+ bufferWidth = bufferHeight;
+ bufferHeight = tmp;
+ }
+ float xScale = float(windowWidth) / float(bufferWidth);
+ float yScale = float(windowHeight) / float(bufferHeight);
+
+ // Compute the crop in post-transform coordinates.
+ Rect crop(mCurrentCrop.transform(mCurrentTransform,
+ mActiveBuffer->getWidth(), mActiveBuffer->getHeight()));
+
+ float left = ceil(xScale * float(crop.left));
+ float right = floor(xScale * float(crop.right));
+ float top = ceil(yScale * float(crop.top));
+ float bottom = floor(yScale * float(crop.bottom));
+
+ tr.transform(mVertices[0], left, top);
+ tr.transform(mVertices[1], left, bottom);
+ tr.transform(mVertices[2], right, bottom);
+ tr.transform(mVertices[3], right, top);
+
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const uint32_t hw_h = hw.getHeight();
+ for (size_t i=0 ; i<4 ; i++)
+ mVertices[i][1] = hw_h - mVertices[i][1];
+
+ mTransformedBounds = tr.transform(
+ Rect(int(left), int(top), int(right), int(bottom)));
+ }
+
// This optimization allows the SurfaceTexture to bake in
// the rotation so hardware overlays can be used
mSurfaceTexture->setTransformHint(getTransformHint());
@@ -317,16 +358,24 @@
}
if (!isProtected()) {
+ // TODO: we could be more subtle with isFixedSize()
+ const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
+
+ // Query the texture matrix given our current filtering mode.
+ float textureMatrix[16];
+ mSurfaceTexture->setFilteringEnabled(useFiltering);
+ mSurfaceTexture->getTransformMatrix(textureMatrix);
+
+ // Set things up for texturing.
glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
GLenum filter = GL_NEAREST;
- if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
- // TODO: we could be more subtle with isFixedSize()
+ if (useFiltering) {
filter = GL_LINEAR;
}
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
glMatrixMode(GL_TEXTURE);
- glLoadMatrixf(mTextureMatrix);
+ glLoadMatrixf(textureMatrix);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_EXTERNAL_OES);
@@ -481,7 +530,7 @@
mFlinger->invalidateHwcGeometry();
}
- const Rect crop(mSurfaceTexture->getCurrentCrop());
+ Rect crop(mSurfaceTexture->getCurrentCrop());
const uint32_t transform(mSurfaceTexture->getCurrentTransform());
const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
if ((crop != mCurrentCrop) ||
@@ -494,13 +543,6 @@
mFlinger->invalidateHwcGeometry();
}
- GLfloat textureMatrix[16];
- mSurfaceTexture->getTransformMatrix(textureMatrix);
- if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) {
- memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix));
- mFlinger->invalidateHwcGeometry();
- }
-
uint32_t bufWidth = mActiveBuffer->getWidth();
uint32_t bufHeight = mActiveBuffer->getHeight();
if (oldActiveBuffer != NULL) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9a04848..1188621 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -114,7 +114,6 @@
// main thread
sp<GraphicBuffer> mActiveBuffer;
- GLfloat mTextureMatrix[16];
Rect mCurrentCrop;
uint32_t mCurrentTransform;
uint32_t mCurrentScalingMode;
diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
index ec74243..4fe261a 100644
--- a/services/surfaceflinger/Transform.h
+++ b/services/surfaceflinger/Transform.h
@@ -77,6 +77,7 @@
Rect makeBounds(int w, int h) const;
void transform(float* point, int x, int y) const;
Region transform(const Region& reg) const;
+ Rect transform(const Rect& bounds) const;
Transform operator * (const Transform& rhs) const;
// for debugging
@@ -112,7 +113,6 @@
// assumes the last row is < 0 , 0 , 1 >
vec2 transform(const vec2& v) const;
vec3 transform(const vec3& v) const;
- Rect transform(const Rect& bounds) const;
uint32_t type() const;
static bool absIsOne(float f);
static bool isZero(float f);