Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
frameworks_native
Commits
958f5011
Commit
958f5011
authored
10 years ago
by
Dan Stoza
Committed by
Gerrit Code Review
10 years ago
Browse files
Options
Download
Plain Diff
Merge "libgui: Allow an IGBProducer to disable allocation"
parents
fb6d43ff
9de7293b
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
150 additions
and
22 deletions
+150
-22
include/gui/BufferQueueCore.h
include/gui/BufferQueueCore.h
+4
-0
include/gui/BufferQueueProducer.h
include/gui/BufferQueueProducer.h
+3
-0
include/gui/IGraphicBufferProducer.h
include/gui/IGraphicBufferProducer.h
+12
-0
include/ui/GraphicBuffer.h
include/ui/GraphicBuffer.h
+3
-0
libs/gui/BufferQueueCore.cpp
libs/gui/BufferQueueCore.cpp
+2
-1
libs/gui/BufferQueueProducer.cpp
libs/gui/BufferQueueProducer.cpp
+48
-20
libs/gui/IGraphicBufferProducer.cpp
libs/gui/IGraphicBufferProducer.cpp
+22
-1
libs/gui/tests/BufferQueue_test.cpp
libs/gui/tests/BufferQueue_test.cpp
+36
-0
libs/ui/GraphicBuffer.cpp
libs/ui/GraphicBuffer.cpp
+10
-0
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
.../surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+4
-0
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
...es/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+1
-0
services/surfaceflinger/MonitoredProducer.cpp
services/surfaceflinger/MonitoredProducer.cpp
+4
-0
services/surfaceflinger/MonitoredProducer.h
services/surfaceflinger/MonitoredProducer.h
+1
-0
No files found.
include/gui/BufferQueueCore.h
View file @
958f5011
...
...
@@ -266,6 +266,10 @@ private:
// mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
// becomes false.
mutable
Condition
mIsAllocatingCondition
;
// mAllowAllocation determines whether dequeueBuffer is allowed to allocate
// new buffers
bool
mAllowAllocation
;
};
// class BufferQueueCore
}
// namespace android
...
...
This diff is collapsed.
Click to expand it.
include/gui/BufferQueueProducer.h
View file @
958f5011
...
...
@@ -172,6 +172,9 @@ public:
virtual
void
allocateBuffers
(
bool
async
,
uint32_t
width
,
uint32_t
height
,
PixelFormat
format
,
uint32_t
usage
);
// See IGraphicBufferProducer::allowAllocation
virtual
status_t
allowAllocation
(
bool
allow
);
private:
// This is required by the IBinder::DeathRecipient interface
virtual
void
binderDied
(
const
wp
<
IBinder
>&
who
);
...
...
This diff is collapsed.
Click to expand it.
include/gui/IGraphicBufferProducer.h
View file @
958f5011
...
...
@@ -458,6 +458,18 @@ public:
// allocated, this function has no effect.
virtual
void
allocateBuffers
(
bool
async
,
uint32_t
width
,
uint32_t
height
,
PixelFormat
format
,
uint32_t
usage
)
=
0
;
// Sets whether dequeueBuffer is allowed to allocate new buffers.
//
// Normally dequeueBuffer does not discriminate between free slots which
// already have an allocated buffer and those which do not, and will
// allocate a new buffer if the slot doesn't have a buffer or if the slot's
// buffer doesn't match the requested size, format, or usage. This method
// allows the producer to restrict the eligible slots to those which already
// have an allocated buffer of the correct size, format, and usage. If no
// eligible slot is available, dequeueBuffer will block or return an error
// as usual.
virtual
status_t
allowAllocation
(
bool
allow
)
=
0
;
};
// ----------------------------------------------------------------------------
...
...
This diff is collapsed.
Click to expand it.
include/ui/GraphicBuffer.h
View file @
958f5011
...
...
@@ -97,6 +97,9 @@ public:
status_t
reallocate
(
uint32_t
inWidth
,
uint32_t
inHeight
,
PixelFormat
inFormat
,
uint32_t
inUsage
);
bool
needsReallocation
(
uint32_t
inWidth
,
uint32_t
inHeight
,
PixelFormat
inFormat
,
uint32_t
inUsage
);
status_t
lock
(
uint32_t
inUsage
,
void
**
vaddr
);
status_t
lock
(
uint32_t
inUsage
,
const
Rect
&
rect
,
void
**
vaddr
);
// For HAL_PIXEL_FORMAT_YCbCr_420_888
...
...
This diff is collapsed.
Click to expand it.
libs/gui/BufferQueueCore.cpp
View file @
958f5011
...
...
@@ -69,7 +69,8 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
mFrameCounter
(
0
),
mTransformHint
(
0
),
mIsAllocating
(
false
),
mIsAllocatingCondition
()
mIsAllocatingCondition
(),
mAllowAllocation
(
true
)
{
if
(
allocator
==
NULL
)
{
sp
<
ISurfaceComposer
>
composer
(
ComposerService
::
getComposerService
());
...
...
This diff is collapsed.
Click to expand it.
libs/gui/BufferQueueProducer.cpp
View file @
958f5011
...
...
@@ -219,7 +219,7 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
auto
slot
=
mCore
->
mFreeBuffers
.
begin
();
*
found
=
*
slot
;
mCore
->
mFreeBuffers
.
erase
(
slot
);
}
else
if
(
!
mCore
->
mFreeSlots
.
empty
())
{
}
else
if
(
mCore
->
mAllowAllocation
&&
!
mCore
->
mFreeSlots
.
empty
())
{
auto
slot
=
mCore
->
mFreeSlots
.
begin
();
// Only return free slots up to the max buffer count
if
(
*
slot
<
maxBufferCount
)
{
...
...
@@ -285,17 +285,39 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
// Enable the usage bits the consumer requested
usage
|=
mCore
->
mConsumerUsageBits
;
int
found
;
status_t
status
=
waitForFreeSlotThenRelock
(
"dequeueBuffer"
,
async
,
&
found
,
&
returnFlags
);
if
(
status
!=
NO_ERROR
)
{
return
status
;
const
bool
useDefaultSize
=
!
width
&&
!
height
;
if
(
useDefaultSize
)
{
width
=
mCore
->
mDefaultWidth
;
height
=
mCore
->
mDefaultHeight
;
}
// This should not happen
if
(
found
==
BufferQueueCore
::
INVALID_BUFFER_SLOT
)
{
BQ_LOGE
(
"dequeueBuffer: no available buffer slots"
);
return
-
EBUSY
;
int
found
=
BufferItem
::
INVALID_BUFFER_SLOT
;
while
(
found
==
BufferItem
::
INVALID_BUFFER_SLOT
)
{
status_t
status
=
waitForFreeSlotThenRelock
(
"dequeueBuffer"
,
async
,
&
found
,
&
returnFlags
);
if
(
status
!=
NO_ERROR
)
{
return
status
;
}
// This should not happen
if
(
found
==
BufferQueueCore
::
INVALID_BUFFER_SLOT
)
{
BQ_LOGE
(
"dequeueBuffer: no available buffer slots"
);
return
-
EBUSY
;
}
const
sp
<
GraphicBuffer
>&
buffer
(
mSlots
[
found
].
mGraphicBuffer
);
// If we are not allowed to allocate new buffers,
// waitForFreeSlotThenRelock must have returned a slot containing a
// buffer. If this buffer would require reallocation to meet the
// requested attributes, we free it and attempt to get another one.
if
(
!
mCore
->
mAllowAllocation
)
{
if
(
buffer
->
needsReallocation
(
width
,
height
,
format
,
usage
))
{
mCore
->
freeBufferLocked
(
found
);
found
=
BufferItem
::
INVALID_BUFFER_SLOT
;
continue
;
}
}
}
*
outSlot
=
found
;
...
...
@@ -303,20 +325,11 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
attachedByConsumer
=
mSlots
[
found
].
mAttachedByConsumer
;
const
bool
useDefaultSize
=
!
width
&&
!
height
;
if
(
useDefaultSize
)
{
width
=
mCore
->
mDefaultWidth
;
height
=
mCore
->
mDefaultHeight
;
}
mSlots
[
found
].
mBufferState
=
BufferSlot
::
DEQUEUED
;
const
sp
<
GraphicBuffer
>&
buffer
(
mSlots
[
found
].
mGraphicBuffer
);
if
((
buffer
==
NULL
)
||
(
static_cast
<
uint32_t
>
(
buffer
->
width
)
!=
width
)
||
(
static_cast
<
uint32_t
>
(
buffer
->
height
)
!=
height
)
||
(
buffer
->
format
!=
format
)
||
((
static_cast
<
uint32_t
>
(
buffer
->
usage
)
&
usage
)
!=
usage
))
buffer
->
needsReallocation
(
width
,
height
,
format
,
usage
))
{
mSlots
[
found
].
mAcquireCalled
=
false
;
mSlots
[
found
].
mGraphicBuffer
=
NULL
;
...
...
@@ -933,6 +946,12 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
Mutex
::
Autolock
lock
(
mCore
->
mMutex
);
mCore
->
waitWhileAllocatingLocked
();
if
(
!
mCore
->
mAllowAllocation
)
{
BQ_LOGE
(
"allocateBuffers: allocation is not allowed for this "
"BufferQueue"
);
return
;
}
int
currentBufferCount
=
0
;
for
(
int
slot
=
0
;
slot
<
BufferQueueDefs
::
NUM_BUFFER_SLOTS
;
++
slot
)
{
if
(
mSlots
[
slot
].
mGraphicBuffer
!=
NULL
)
{
...
...
@@ -1027,6 +1046,15 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
}
}
status_t
BufferQueueProducer
::
allowAllocation
(
bool
allow
)
{
ATRACE_CALL
();
BQ_LOGV
(
"allowAllocation: %s"
,
allow
?
"true"
:
"false"
);
Mutex
::
Autolock
lock
(
mCore
->
mMutex
);
mCore
->
mAllowAllocation
=
allow
;
return
NO_ERROR
;
}
void
BufferQueueProducer
::
binderDied
(
const
wp
<
android
::
IBinder
>&
/* who */
)
{
// If we're here, it means that a producer we were connected to died.
// We're guaranteed that we are still connected to it because we remove
...
...
This diff is collapsed.
Click to expand it.
libs/gui/IGraphicBufferProducer.cpp
View file @
958f5011
...
...
@@ -46,6 +46,7 @@ enum {
DISCONNECT
,
SET_SIDEBAND_STREAM
,
ALLOCATE_BUFFERS
,
ALLOW_ALLOCATION
,
};
class
BpGraphicBufferProducer
:
public
BpInterface
<
IGraphicBufferProducer
>
...
...
@@ -271,6 +272,18 @@ public:
ALOGE
(
"allocateBuffers failed to transact: %d"
,
result
);
}
}
virtual
status_t
allowAllocation
(
bool
allow
)
{
Parcel
data
,
reply
;
data
.
writeInterfaceToken
(
IGraphicBufferProducer
::
getInterfaceDescriptor
());
data
.
writeInt32
(
static_cast
<
int32_t
>
(
allow
));
status_t
result
=
remote
()
->
transact
(
ALLOW_ALLOCATION
,
data
,
&
reply
);
if
(
result
!=
NO_ERROR
)
{
return
result
;
}
result
=
reply
.
readInt32
();
return
result
;
}
};
// Out-of-line virtual method definition to trigger vtable emission in this
...
...
@@ -418,7 +431,7 @@ status_t BnGraphicBufferProducer::onTransact(
reply
->
writeInt32
(
result
);
return
NO_ERROR
;
}
case
ALLOCATE_BUFFERS
:
case
ALLOCATE_BUFFERS
:
{
CHECK_INTERFACE
(
IGraphicBufferProducer
,
data
,
reply
);
bool
async
=
static_cast
<
bool
>
(
data
.
readInt32
());
uint32_t
width
=
data
.
readUint32
();
...
...
@@ -427,6 +440,14 @@ status_t BnGraphicBufferProducer::onTransact(
uint32_t
usage
=
data
.
readUint32
();
allocateBuffers
(
async
,
width
,
height
,
format
,
usage
);
return
NO_ERROR
;
}
case
ALLOW_ALLOCATION
:
{
CHECK_INTERFACE
(
IGraphicBufferProducer
,
data
,
reply
);
bool
allow
=
static_cast
<
bool
>
(
data
.
readInt32
());
status_t
result
=
allowAllocation
(
allow
);
reply
->
writeInt32
(
result
);
return
NO_ERROR
;
}
}
return
BBinder
::
onTransact
(
code
,
data
,
reply
,
flags
);
}
...
...
This diff is collapsed.
Click to expand it.
libs/gui/tests/BufferQueue_test.cpp
View file @
958f5011
...
...
@@ -366,4 +366,40 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
ASSERT_EQ
(
OK
,
item
.
mGraphicBuffer
->
unlock
());
}
TEST_F
(
BufferQueueTest
,
TestDisallowingAllocation
)
{
createBufferQueue
();
sp
<
DummyConsumer
>
dc
(
new
DummyConsumer
);
ASSERT_EQ
(
OK
,
mConsumer
->
consumerConnect
(
dc
,
true
));
IGraphicBufferProducer
::
QueueBufferOutput
output
;
ASSERT_EQ
(
OK
,
mProducer
->
connect
(
new
DummyProducerListener
,
NATIVE_WINDOW_API_CPU
,
true
,
&
output
));
static
const
uint32_t
WIDTH
=
320
;
static
const
uint32_t
HEIGHT
=
240
;
ASSERT_EQ
(
OK
,
mConsumer
->
setDefaultBufferSize
(
WIDTH
,
HEIGHT
));
int
slot
;
sp
<
Fence
>
fence
;
sp
<
GraphicBuffer
>
buffer
;
// This should return an error since it would require an allocation
ASSERT_EQ
(
OK
,
mProducer
->
allowAllocation
(
false
));
ASSERT_EQ
(
WOULD_BLOCK
,
mProducer
->
dequeueBuffer
(
&
slot
,
&
fence
,
false
,
0
,
0
,
0
,
GRALLOC_USAGE_SW_WRITE_OFTEN
));
// This should succeed, now that we've lifted the prohibition
ASSERT_EQ
(
OK
,
mProducer
->
allowAllocation
(
true
));
ASSERT_EQ
(
IGraphicBufferProducer
::
BUFFER_NEEDS_REALLOCATION
,
mProducer
->
dequeueBuffer
(
&
slot
,
&
fence
,
false
,
0
,
0
,
0
,
GRALLOC_USAGE_SW_WRITE_OFTEN
));
// Release the previous buffer back to the BufferQueue
mProducer
->
cancelBuffer
(
slot
,
fence
);
// This should fail since we're requesting a different size
ASSERT_EQ
(
OK
,
mProducer
->
allowAllocation
(
false
));
ASSERT_EQ
(
WOULD_BLOCK
,
mProducer
->
dequeueBuffer
(
&
slot
,
&
fence
,
false
,
WIDTH
*
2
,
HEIGHT
*
2
,
0
,
GRALLOC_USAGE_SW_WRITE_OFTEN
));
}
}
// namespace android
This diff is collapsed.
Click to expand it.
libs/ui/GraphicBuffer.cpp
View file @
958f5011
...
...
@@ -152,6 +152,16 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight,
return
initSize
(
inWidth
,
inHeight
,
inFormat
,
inUsage
);
}
bool
GraphicBuffer
::
needsReallocation
(
uint32_t
inWidth
,
uint32_t
inHeight
,
PixelFormat
inFormat
,
uint32_t
inUsage
)
{
if
(
static_cast
<
int
>
(
inWidth
)
!=
width
)
return
true
;
if
(
static_cast
<
int
>
(
inHeight
)
!=
height
)
return
true
;
if
(
inFormat
!=
format
)
return
true
;
if
((
static_cast
<
uint32_t
>
(
usage
)
&
inUsage
)
!=
inUsage
)
return
true
;
return
false
;
}
status_t
GraphicBuffer
::
initSize
(
uint32_t
inWidth
,
uint32_t
inHeight
,
PixelFormat
inFormat
,
uint32_t
inUsage
)
{
...
...
This diff is collapsed.
Click to expand it.
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
View file @
958f5011
...
...
@@ -526,6 +526,10 @@ void VirtualDisplaySurface::allocateBuffers(bool /* async */,
// TODO: Should we actually allocate buffers for a virtual display?
}
status_t
VirtualDisplaySurface
::
allowAllocation
(
bool
/* allow */
)
{
return
INVALID_OPERATION
;
}
void
VirtualDisplaySurface
::
updateQueueBufferOutput
(
const
QueueBufferOutput
&
qbo
)
{
uint32_t
w
,
h
,
transformHint
,
numPendingBuffers
;
...
...
This diff is collapsed.
Click to expand it.
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
View file @
958f5011
...
...
@@ -115,6 +115,7 @@ private:
virtual
status_t
setSidebandStream
(
const
sp
<
NativeHandle
>&
stream
);
virtual
void
allocateBuffers
(
bool
async
,
uint32_t
width
,
uint32_t
height
,
PixelFormat
format
,
uint32_t
usage
);
virtual
status_t
allowAllocation
(
bool
allow
);
//
// Utility methods
...
...
This diff is collapsed.
Click to expand it.
services/surfaceflinger/MonitoredProducer.cpp
View file @
958f5011
...
...
@@ -110,6 +110,10 @@ void MonitoredProducer::allocateBuffers(bool async, uint32_t width,
mProducer
->
allocateBuffers
(
async
,
width
,
height
,
format
,
usage
);
}
status_t
MonitoredProducer
::
allowAllocation
(
bool
allow
)
{
return
mProducer
->
allowAllocation
(
allow
);
}
IBinder
*
MonitoredProducer
::
onAsBinder
()
{
return
IInterface
::
asBinder
(
mProducer
).
get
();
}
...
...
This diff is collapsed.
Click to expand it.
services/surfaceflinger/MonitoredProducer.h
View file @
958f5011
...
...
@@ -53,6 +53,7 @@ public:
virtual
status_t
setSidebandStream
(
const
sp
<
NativeHandle
>&
stream
);
virtual
void
allocateBuffers
(
bool
async
,
uint32_t
width
,
uint32_t
height
,
PixelFormat
format
,
uint32_t
usage
);
virtual
status_t
allowAllocation
(
bool
allow
);
virtual
IBinder
*
onAsBinder
();
private:
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment