summaryrefslogtreecommitdiff
path: root/libs/gui/Surface.cpp
diff options
context:
space:
mode:
author John Reck <jreck@google.com> 2021-05-18 00:42:56 -0400
committer John Reck <jreck@google.com> 2021-05-19 14:46:53 -0400
commitaa5a0b26bbeb37f60e091729405bd57169d1dcbc (patch)
tree6a599a026aa27aa6bb578519b34975cf9bc357b4 /libs/gui/Surface.cpp
parent18c797058c7b4a02a0af26f73115beb448650135 (diff)
Add a better getLastQueuedBuffer
Avoid obfuscation via a matrix that's not necessarily useful or in the desired origin of the caller. Instead return the source data, which is also a lot smaller than the matrix is... Bug: 183553027 Test: atest android.view.cts.PixelCopyTest (+new testBufferQueueCrop) Change-Id: I1f7b5981405b2f20293bce9119414fc7780b8eb6
Diffstat (limited to 'libs/gui/Surface.cpp')
-rw-r--r--libs/gui/Surface.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 2fc9d47b89..89e80c1808 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1492,6 +1492,9 @@ int Surface::perform(int operation, va_list args)
case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER:
res = dispatchGetLastQueuedBuffer(args);
break;
+ case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER2:
+ res = dispatchGetLastQueuedBuffer2(args);
+ break;
case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO:
res = dispatchSetFrameTimelineInfo(args);
break;
@@ -1805,6 +1808,39 @@ int Surface::dispatchGetLastQueuedBuffer(va_list args) {
return result;
}
+int Surface::dispatchGetLastQueuedBuffer2(va_list args) {
+ AHardwareBuffer** buffer = va_arg(args, AHardwareBuffer**);
+ int* fence = va_arg(args, int*);
+ ARect* crop = va_arg(args, ARect*);
+ uint32_t* transform = va_arg(args, uint32_t*);
+ sp<GraphicBuffer> graphicBuffer;
+ sp<Fence> spFence;
+
+ Rect r;
+ int result =
+ mGraphicBufferProducer->getLastQueuedBuffer(&graphicBuffer, &spFence, &r, transform);
+
+ if (graphicBuffer != nullptr) {
+ *buffer = graphicBuffer->toAHardwareBuffer();
+ AHardwareBuffer_acquire(*buffer);
+
+ // Avoid setting crop* unless buffer is valid (matches IGBP behavior)
+ crop->left = r.left;
+ crop->top = r.top;
+ crop->right = r.right;
+ crop->bottom = r.bottom;
+ } else {
+ *buffer = nullptr;
+ }
+
+ if (spFence != nullptr) {
+ *fence = spFence->dup();
+ } else {
+ *fence = -1;
+ }
+ return result;
+}
+
int Surface::dispatchSetFrameTimelineInfo(va_list args) {
ATRACE_CALL();
auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t));