Merge "Break dependency of libui on libbinder"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 6dbb967..67172b6 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1339,6 +1339,30 @@
return std::string(hash_buffer);
}
+static void SendShellBroadcast(const std::string& action, const std::vector<std::string>& args) {
+ std::vector<std::string> am = {
+ "/system/bin/cmd", "activity", "broadcast", "--user", "0", "-a", action};
+
+ am.insert(am.end(), args.begin(), args.end());
+
+ // TODO: explicity setting Shell's component to allow broadcast to launch it.
+ // That might break other components that are listening to the bugreport notifications
+ // (android.intent.action.BUGREPORT_STARTED and android.intent.action.BUGREPORT_STOPED), but
+ // those should be just handled by Shell anyways.
+ // A more generic alternative would be passing the -f 0x01000000 flag (or whatever
+ // value is defined by FLAG_RECEIVER_INCLUDE_BACKGROUND), but that would reset the
+ // --receiver-foreground option
+ am.push_back("com.android.shell");
+
+ RunCommand("", am,
+ CommandOptions::WithTimeout(20)
+ .Log("Sending broadcast: '%s'\n")
+ .Always()
+ .DropRoot()
+ .RedirectStderr()
+ .Build());
+}
+
int main(int argc, char *argv[]) {
int do_add_date = 0;
int do_zip_file = 0;
@@ -1561,18 +1585,15 @@
if (do_broadcast) {
// clang-format off
- // NOTE: flag must be kept in sync when the value of
- // FLAG_RECEIVER_INCLUDE_BACKGROUND is changed.
std::vector<std::string> am_args = {
"--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
- "-f", "0x01000000",
"--es", "android.intent.extra.NAME", ds.name_,
"--ei", "android.intent.extra.ID", std::to_string(ds.id_),
"--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
"--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
};
// clang-format on
- send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args);
+ SendShellBroadcast("android.intent.action.BUGREPORT_STARTED", am_args);
}
if (use_control_socket) {
dprintf(ds.control_socket_fd_, "BEGIN:%s\n", ds.path_.c_str());
@@ -1805,11 +1826,8 @@
MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
// clang-format off
- // NOTE: flag must be kept in sync when the value of
- // FLAG_RECEIVER_INCLUDE_BACKGROUND is changed.
std::vector<std::string> am_args = {
"--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
- "-f", "0x01000000",
"--ei", "android.intent.extra.ID", std::to_string(ds.id_),
"--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
"--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
@@ -1826,9 +1844,9 @@
am_args.push_back("--es");
am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
am_args.push_back(SHA256_file_hash(ds.path_));
- send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
+ SendShellBroadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
} else {
- send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
+ SendShellBroadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
}
} else {
MYLOGE("Skipping finished broadcast because bugreport could not be generated\n");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index b2cd241..d988429 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -363,9 +363,6 @@
int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
int (*dump_from_fd)(const char* title, const char* path, int fd));
-/* sends a broadcast using Activity Manager */
-void send_broadcast(const std::string& action, const std::vector<std::string>& args);
-
/* prints all the system properties */
void print_properties();
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 0fc2bce..baa6458 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -710,20 +710,6 @@
RunCommand(title, dumpsys, options);
}
-void send_broadcast(const std::string& action, const std::vector<std::string>& args) {
- std::vector<std::string> am = {
- "/system/bin/cmd", "activity", "broadcast", "--user", "0", "-a", action};
-
- am.insert(am.end(), args.begin(), args.end());
-
- RunCommand("", am, CommandOptions::WithTimeout(20)
- .Log("Sending broadcast: '%s'\n")
- .Always()
- .DropRoot()
- .RedirectStderr()
- .Build());
-}
-
size_t num_props = 0;
static char* props[2000];
diff --git a/include/android/bitmap.h b/include/android/bitmap.h
index 261e64f..2def64d 100644
--- a/include/android/bitmap.h
+++ b/include/android/bitmap.h
@@ -56,9 +56,9 @@
ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,
/** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/
ANDROID_BITMAP_FORMAT_RGB_565 = 4,
- /** Red: 4 bits, Green: 4 bits, Blue: 4 bits, Alpha: 4 bits. **/
+ /** Deprecated in API level 13. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead. **/
ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,
- /** Deprecated. */
+ /** Alpha: 8 bits. */
ANDROID_BITMAP_FORMAT_A_8 = 8,
};
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index f8ded74..4a49f53 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -172,7 +172,9 @@
void setFilteringEnabled(bool enabled);
// getCurrentBuffer returns the buffer associated with the current image.
- sp<GraphicBuffer> getCurrentBuffer() const;
+ // When outSlot is not nullptr, the current buffer slot index is also
+ // returned.
+ sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr) const;
// getCurrentTextureTarget returns the texture target of the current
// texture as returned by updateTexImage().
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 54f4cd3..95ca0f3 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -91,6 +91,12 @@
uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride,
native_handle_t* inHandle, bool keepOwnership);
+ // create a buffer from an existing handle using gralloc1
+ GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
+ uint32_t inLayerCount, uint32_t inProducerUsage,
+ uint32_t inConsumerUsage, uint32_t inStride,
+ native_handle_t* inHandle, bool keepOwnership);
+
// create a buffer from an existing ANativeWindowBuffer
GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index b11a3e5..9532c52 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -930,9 +930,14 @@
return mCurrentFrameNumber;
}
-sp<GraphicBuffer> GLConsumer::getCurrentBuffer() const {
+sp<GraphicBuffer> GLConsumer::getCurrentBuffer(int* outSlot) const {
Mutex::Autolock lock(mMutex);
- return (mCurrentTextureImage == NULL) ?
+
+ if (outSlot != nullptr) {
+ *outSlot = mCurrentTexture;
+ }
+
+ return (mCurrentTextureImage == nullptr) ?
NULL : mCurrentTextureImage->graphicBuffer();
}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index d29bae1..5ef95ec 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -104,6 +104,24 @@
handle = inHandle;
}
+GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
+ PixelFormat inFormat, uint32_t inLayerCount, uint32_t inProducerUsage,
+ uint32_t inConsumerUsage, uint32_t inStride,
+ native_handle_t* inHandle, bool keepOwnership)
+ : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
+ mBufferMapper(GraphicBufferMapper::get()),
+ mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
+{
+ width = static_cast<int>(inWidth);
+ height = static_cast<int>(inHeight);
+ stride = static_cast<int>(inStride);
+ format = inFormat;
+ layerCount = inLayerCount;
+ usage = static_cast<int>(inConsumerUsage | inProducerUsage);
+ handle = inHandle;
+}
+
+
GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
mBufferMapper(GraphicBufferMapper::get()),
diff --git a/libs/vr/libdisplay/include/private/dvr/display_rpc.h b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
index 6150b35..1c1a5e0 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_rpc.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
@@ -205,7 +205,7 @@
struct DisplayRPC {
// Service path.
- static constexpr char kClientPath[] = "system/display/client";
+ static constexpr char kClientPath[] = "system/vr/display/client";
// Op codes.
enum {
@@ -253,7 +253,7 @@
struct DisplayManagerRPC {
// Service path.
- static constexpr char kClientPath[] = "system/display/manager";
+ static constexpr char kClientPath[] = "system/vr/display/manager";
// Op codes.
enum {
@@ -287,7 +287,7 @@
struct DisplayScreenshotRPC {
// Service path.
- static constexpr char kClientPath[] = "system/display/screenshot";
+ static constexpr char kClientPath[] = "system/vr/display/screenshot";
// Op codes.
enum {
@@ -314,7 +314,7 @@
struct DisplayVSyncRPC {
// Service path.
- static constexpr char kClientPath[] = "system/display/vsync";
+ static constexpr char kClientPath[] = "system/vr/display/vsync";
// Op codes.
enum {
diff --git a/libs/vr/libsensor/include/private/dvr/pose-ipc.h b/libs/vr/libsensor/include/private/dvr/pose-ipc.h
index 908030e..0616d46 100644
--- a/libs/vr/libsensor/include/private/dvr/pose-ipc.h
+++ b/libs/vr/libsensor/include/private/dvr/pose-ipc.h
@@ -7,7 +7,7 @@
extern "C" {
#endif
-#define DVR_POSE_SERVICE_BASE "system/pose"
+#define DVR_POSE_SERVICE_BASE "system/vr/pose"
#define DVR_POSE_SERVICE_CLIENT (DVR_POSE_SERVICE_BASE "/client")
enum {
diff --git a/libs/vr/libsensor/include/private/dvr/sensor-ipc.h b/libs/vr/libsensor/include/private/dvr/sensor-ipc.h
index 7e8b9e5..b2ebd95 100644
--- a/libs/vr/libsensor/include/private/dvr/sensor-ipc.h
+++ b/libs/vr/libsensor/include/private/dvr/sensor-ipc.h
@@ -1,7 +1,7 @@
#ifndef ANDROID_DVR_SENSOR_IPC_H_
#define ANDROID_DVR_SENSOR_IPC_H_
-#define DVR_SENSOR_SERVICE_BASE "system/sensors"
+#define DVR_SENSOR_SERVICE_BASE "system/vr/sensors"
#define DVR_SENSOR_SERVICE_CLIENT (DVR_SENSOR_SERVICE_BASE "/client")
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index d0e4493..5253b26 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -1501,7 +1501,8 @@
if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
- hardware_composer_layer_, handle,
+ hardware_composer_layer_, 0,
+ handle,
acquire_fence_fd_.Get());
ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 662f320..b096e1c 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -189,13 +189,16 @@
if (fstat(fd1, &s1) < 0 || fstat(fd2, &s2) < 0 || s1.st_ino == s2.st_ino) {
ret = true;
}
+ break;
}
case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
LOG_FATAL("%s: Implement GRALLOC or remove", __FUNCTION__);
ret = true;
+ break;
default:
ALOGE("Unexpected mem type %d", mMem.type);
ret = true;
+ break;
}
}
return ret;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 1bd9616..6cb1af1 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -20,6 +20,7 @@
#include <android/dvr/composer/1.0/IVrComposerClient.h>
#include <inttypes.h>
#include <log/log.h>
+#include <gui/BufferQueue.h>
#include "ComposerHal.h"
@@ -221,9 +222,8 @@
Error Composer::createLayer(Display display, Layer* outLayer)
{
- const uint32_t bufferSlotCount = 1;
Error error = kDefaultError;
- mClient->createLayer(display, bufferSlotCount,
+ mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
[&](const auto& tmpError, const auto& tmpLayer) {
error = tmpError;
if (error != Error::NONE) {
@@ -427,12 +427,13 @@
return unwrapRet(ret);
}
-Error Composer::setClientTarget(Display display, const native_handle_t* target,
+Error Composer::setClientTarget(Display display, uint32_t slot,
+ const native_handle_t* target,
int acquireFence, Dataspace dataspace,
const std::vector<IComposerClient::Rect>& damage)
{
mWriter.selectDisplay(display);
- mWriter.setClientTarget(0, target, acquireFence, dataspace, damage);
+ mWriter.setClientTarget(slot, target, acquireFence, dataspace, damage);
return Error::NONE;
}
@@ -472,7 +473,7 @@
Error Composer::setClientTargetSlotCount(Display display)
{
- const uint32_t bufferSlotCount = 1;
+ const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
return unwrapRet(ret);
}
@@ -503,11 +504,11 @@
}
Error Composer::setLayerBuffer(Display display, Layer layer,
- const native_handle_t* buffer, int acquireFence)
+ uint32_t slot, const native_handle_t* buffer, int acquireFence)
{
mWriter.selectDisplay(display);
mWriter.selectLayer(layer);
- mWriter.setLayerBuffer(0, buffer, acquireFence);
+ mWriter.setLayerBuffer(slot, buffer, acquireFence);
return Error::NONE;
}
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 329d787..1ede705 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -172,7 +172,14 @@
Error presentDisplay(Display display, int* outPresentFence);
Error setActiveConfig(Display display, Config config);
- Error setClientTarget(Display display, const native_handle_t* target,
+
+ /*
+ * The composer caches client targets internally. When target is nullptr,
+ * the composer uses slot to look up the client target from its cache.
+ * When target is not nullptr, the cache is updated with the new target.
+ */
+ Error setClientTarget(Display display, uint32_t slot,
+ const native_handle_t* target,
int acquireFence, Dataspace dataspace,
const std::vector<IComposerClient::Rect>& damage);
Error setColorMode(Display display, ColorMode mode);
@@ -190,7 +197,8 @@
Error setCursorPosition(Display display, Layer layer,
int32_t x, int32_t y);
- Error setLayerBuffer(Display display, Layer layer,
+ /* see setClientTarget for the purpose of slot */
+ Error setLayerBuffer(Display display, Layer layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence);
Error setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& damage);
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
index d801bb3..cb08f08 100644
--- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -25,6 +25,7 @@
namespace android {
// ---------------------------------------------------------------------------
+class Fence;
class IGraphicBufferProducer;
class String8;
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 1998edf..d3d0d51 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -100,16 +100,18 @@
status_t FramebufferSurface::advanceFrame() {
#ifdef USE_HWC2
+ uint32_t slot = 0;
sp<GraphicBuffer> buf;
sp<Fence> acquireFence(Fence::NO_FENCE);
android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
- status_t result = nextBuffer(buf, acquireFence, dataspace);
+ status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
if (result != NO_ERROR) {
ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
strerror(-result), result);
return result;
}
- result = mHwc.setClientTarget(mDisplayType, acquireFence, buf, dataspace);
+ result = mHwc.setClientTarget(mDisplayType, slot,
+ acquireFence, buf, dataspace);
if (result != NO_ERROR) {
ALOGE("error posting framebuffer: %d", result);
}
@@ -123,8 +125,9 @@
}
#ifdef USE_HWC2
-status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer,
- sp<Fence>& outFence, android_dataspace_t& outDataspace) {
+status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
+ sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
+ android_dataspace_t& outDataspace) {
#else
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
#endif
@@ -133,7 +136,12 @@
BufferItem item;
status_t err = acquireBufferLocked(&item, 0);
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
+#ifdef USE_HWC2
+ mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
+ &outSlot, &outBuffer);
+#else
outBuffer = mCurrentBuffer;
+#endif
return NO_ERROR;
} else if (err != NO_ERROR) {
ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
@@ -169,9 +177,12 @@
mCurrentFence = item.mFence;
outFence = item.mFence;
- outBuffer = mCurrentBuffer;
#ifdef USE_HWC2
+ mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
+ &outSlot, &outBuffer);
outDataspace = item.mDataSpace;
+#else
+ outBuffer = mCurrentBuffer;
#endif
return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 439435a..5eea6b6 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -17,12 +17,14 @@
#ifndef ANDROID_SF_FRAMEBUFFER_SURFACE_H
#define ANDROID_SF_FRAMEBUFFER_SURFACE_H
+#include "DisplaySurface.h"
+
#include <stdint.h>
#include <sys/types.h>
#include <gui/ConsumerBase.h>
-#include "DisplaySurface.h"
+#include <memory>
// ---------------------------------------------------------------------------
namespace android {
@@ -31,6 +33,7 @@
class Rect;
class String8;
class HWComposer;
+class HWComposerBufferCache;
// ---------------------------------------------------------------------------
@@ -68,8 +71,8 @@
// BufferQueue and releases the previously latched buffer to the
// BufferQueue. The new buffer is returned in the 'buffer' argument.
#ifdef USE_HWC2
- status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
- android_dataspace_t& outDataspace);
+ status_t nextBuffer(uint32_t& outSlot, sp<GraphicBuffer>& outBuffer,
+ sp<Fence>& outFence, android_dataspace_t& outDataspace);
#else
status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
#endif
@@ -93,6 +96,9 @@
HWComposer& mHwc;
#ifdef USE_HWC2
+ std::unique_ptr<HWComposerBufferCache> mHwcBufferCache =
+ std::make_unique<HWComposerBufferCache>();
+
// Previous buffer to release after getting an updated retire fence
bool mHasPendingRelease;
int mPreviousBufferSlot;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 6ff5ea1..99a6d71 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -962,17 +962,18 @@
return static_cast<Error>(intError);
}
-Error Display::setClientTarget(buffer_handle_t target,
+Error Display::setClientTarget(uint32_t slot, buffer_handle_t target,
const sp<Fence>& acquireFence, android_dataspace_t dataspace)
{
// TODO: Properly encode client target surface damage
int32_t fenceFd = acquireFence->dup();
#ifdef BYPASS_IHWC
+ (void) slot;
int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
#else
- auto intError = mDevice.mComposer->setClientTarget(mId, target, fenceFd,
- static_cast<Hwc2::Dataspace>(dataspace),
+ auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
+ fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
std::vector<Hwc2::IComposerClient::Rect>());
#endif
return static_cast<Error>(intError);
@@ -1195,16 +1196,17 @@
return static_cast<Error>(intError);
}
-Error Layer::setBuffer(buffer_handle_t buffer,
+Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
const sp<Fence>& acquireFence)
{
int32_t fenceFd = acquireFence->dup();
#ifdef BYPASS_IHWC
+ (void) slot;
int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
mId, buffer, fenceFd);
#else
auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
- mId, buffer, fenceFd);
+ mId, slot, buffer, fenceFd);
#endif
return static_cast<Error>(intError);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 256b05d..d770f22 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -322,7 +322,7 @@
[[clang::warn_unused_result]] Error setActiveConfig(
const std::shared_ptr<const Config>& config);
[[clang::warn_unused_result]] Error setClientTarget(
- buffer_handle_t target,
+ uint32_t slot, buffer_handle_t target,
const android::sp<android::Fence>& acquireFence,
android_dataspace_t dataspace);
[[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
@@ -384,7 +384,8 @@
hwc2_layer_t getId() const { return mId; }
[[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
- [[clang::warn_unused_result]] Error setBuffer(buffer_handle_t buffer,
+ [[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
+ buffer_handle_t buffer,
const android::sp<android::Fence>& acquireFence);
[[clang::warn_unused_result]] Error setSurfaceDamage(
const android::Region& damage);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 7914770..e86a071 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -444,7 +444,7 @@
}
}
-status_t HWComposer::setClientTarget(int32_t displayId,
+status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
android_dataspace_t dataspace) {
if (!isValidDisplay(displayId)) {
@@ -457,7 +457,8 @@
if ((target != nullptr) && target->getNativeBuffer()) {
handle = target->getNativeBuffer()->handle;
}
- auto error = hwcDisplay->setClientTarget(handle, acquireFence, dataspace);
+ auto error = hwcDisplay->setClientTarget(slot, handle,
+ acquireFence, dataspace);
if (error != HWC2::Error::None) {
ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -894,5 +895,36 @@
*this = DisplayData();
}
+void HWComposerBufferCache::clear()
+{
+ mBuffers.clear();
+}
+
+void HWComposerBufferCache::getHwcBuffer(int slot,
+ const sp<GraphicBuffer>& buffer,
+ uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
+{
+ if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
+ // default to slot 0
+ slot = 0;
+ }
+
+ if (static_cast<size_t>(slot) >= mBuffers.size()) {
+ mBuffers.resize(slot + 1);
+ }
+
+ *outSlot = slot;
+
+ if (mBuffers[slot] == buffer) {
+ // already cached in HWC, skip sending the buffer
+ *outBuffer = nullptr;
+ } else {
+ *outBuffer = buffer;
+
+ // update cache
+ mBuffers[slot] = buffer;
+ }
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 2713505..37f12e4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -26,6 +26,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <gui/BufferQueue.h>
+
#include <ui/Fence.h>
#include <utils/BitSet.h>
@@ -94,7 +96,8 @@
// Asks the HAL what it can do
status_t prepare(DisplayDevice& displayDevice);
- status_t setClientTarget(int32_t displayId, const sp<Fence>& acquireFence,
+ status_t setClientTarget(int32_t displayId, uint32_t slot,
+ const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, android_dataspace_t dataspace);
// Present layers to the display and read releaseFences.
@@ -224,6 +227,19 @@
mutable Mutex mVsyncLock;
};
+class HWComposerBufferCache {
+public:
+ void clear();
+
+ void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer,
+ uint32_t* outSlot, sp<GraphicBuffer>* outBuffer);
+
+private:
+ // a vector as we expect "slot" to be in the range of [0, 63] (that is,
+ // less than BufferQueue::NUM_BUFFER_SLOTS).
+ std::vector<sp<GraphicBuffer>> mBuffers;
+};
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 6a98f03..5f3c388 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -221,9 +221,14 @@
status_t result = NO_ERROR;
if (fbBuffer != NULL) {
#ifdef USE_HWC2
+ uint32_t hwcSlot = 0;
+ sp<GraphicBuffer> hwcBuffer;
+ mHwcBufferCache->getHwcBuffer(mFbProducerSlot, fbBuffer,
+ &hwcSlot, &hwcBuffer);
+
// TODO: Correctly propagate the dataspace from GL composition
- result = mHwc.setClientTarget(mDisplayId, mFbFence, fbBuffer,
- HAL_DATASPACE_UNKNOWN);
+ result = mHwc.setClientTarget(mDisplayId, hwcSlot, mFbFence,
+ hwcBuffer, HAL_DATASPACE_UNKNOWN);
#else
result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
#endif
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index d37dc0a..2636667 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -17,16 +17,19 @@
#ifndef ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
#define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
+#include "DisplaySurface.h"
+
#include <gui/ConsumerBase.h>
#include <gui/IGraphicBufferProducer.h>
-#include "DisplaySurface.h"
+#include <memory>
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
class HWComposer;
+class HWComposerBufferCache;
class IProducerListener;
/* This DisplaySurface implementation supports virtual displays, where GLES
@@ -250,6 +253,11 @@
static const char* dbgSourceStr(Source s);
bool mMustRecompose;
+
+#ifdef USE_HWC2
+ std::unique_ptr<HWComposerBufferCache> mHwcBufferCache =
+ std::make_unique<HWComposerBufferCache>();
+#endif
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e57c19a..3a9bca6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -270,6 +270,16 @@
}
}
+void Layer::onBuffersReleased() {
+#ifdef USE_HWC2
+ Mutex::Autolock lock(mHwcBufferCacheMutex);
+
+ for (auto info : mHwcBufferCaches) {
+ info.second.clear();
+ }
+#endif
+}
+
void Layer::onSidebandStreamChanged() {
if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
// mSidebandStreamChanged was false
@@ -836,8 +846,22 @@
static_cast<int32_t>(error));
}
+ uint32_t hwcSlot = 0;
+ buffer_handle_t hwcHandle = nullptr;
+ {
+ Mutex::Autolock lock(mHwcBufferCacheMutex);
+
+ auto& hwcBufferCache = mHwcBufferCaches[hwcId];
+ sp<GraphicBuffer> hwcBuffer;
+ hwcBufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
+ &hwcSlot, &hwcBuffer);
+ if (hwcBuffer != nullptr) {
+ hwcHandle = hwcBuffer->handle;
+ }
+ }
+
auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
- error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
+ error = hwcLayer->setBuffer(hwcSlot, hwcHandle, acquireFence);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
mActiveBuffer->handle, to_string(error).c_str(),
@@ -2087,7 +2111,8 @@
}
// update the active buffer
- mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
+ mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(
+ &mActiveBufferSlot);
if (mActiveBuffer == NULL) {
// this can only happen if the very first buffer was rejected.
return outDirtyRegion;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7335be7..76c710a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -376,13 +376,20 @@
#ifdef USE_HWC2
// -----------------------------------------------------------------------
+ void eraseHwcLayer(int32_t hwcId) {
+ mHwcLayers.erase(hwcId);
+
+ Mutex::Autolock lock(mHwcBufferCacheMutex);
+ mHwcBufferCaches.erase(hwcId);
+ }
+
bool hasHwcLayer(int32_t hwcId) {
if (mHwcLayers.count(hwcId) == 0) {
return false;
}
if (mHwcLayers[hwcId].layer->isAbandoned()) {
ALOGI("Erasing abandoned layer %s on %d", mName.string(), hwcId);
- mHwcLayers.erase(hwcId);
+ eraseHwcLayer(hwcId);
return false;
}
return true;
@@ -398,8 +405,11 @@
void setHwcLayer(int32_t hwcId, std::shared_ptr<HWC2::Layer>&& layer) {
if (layer) {
mHwcLayers[hwcId].layer = layer;
+
+ Mutex::Autolock lock(mHwcBufferCacheMutex);
+ mHwcBufferCaches[hwcId] = HWComposerBufferCache();
} else {
- mHwcLayers.erase(hwcId);
+ eraseHwcLayer(hwcId);
}
}
@@ -489,6 +499,7 @@
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
virtual void onFrameAvailable(const BufferItem& item) override;
virtual void onFrameReplaced(const BufferItem& item) override;
+ virtual void onBuffersReleased() override;
virtual void onSidebandStreamChanged() override;
void commitTransaction(const State& stateToCommit);
@@ -642,6 +653,7 @@
FenceTimeline mReleaseTimeline;
// main thread
+ int mActiveBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
sp<GraphicBuffer> mActiveBuffer;
sp<NativeHandle> mSidebandStream;
Rect mCurrentCrop;
@@ -681,6 +693,12 @@
gfx::FloatRect sourceCrop;
};
std::unordered_map<int32_t, HWCInfo> mHwcLayers;
+
+ // We need one HWComposerBufferCache for each HWC display. We cannot have
+ // HWComposerBufferCache in HWCInfo because HWCInfo can only be accessed
+ // from the main thread.
+ Mutex mHwcBufferCacheMutex;
+ std::unordered_map<int32_t, HWComposerBufferCache> mHwcBufferCaches;
#else
bool mIsGlesComposition;
#endif
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 029937a..942af13 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -235,6 +235,19 @@
mContentsChangedListener = listener;
}
+void SurfaceFlingerConsumer::onBuffersReleased() {
+ sp<ContentsChangedListener> listener;
+ { // scope for the lock
+ Mutex::Autolock lock(mMutex);
+ ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get());
+ listener = mContentsChangedListener.promote();
+ }
+
+ if (listener != NULL) {
+ listener->onBuffersReleased();
+ }
+}
+
void SurfaceFlingerConsumer::onSidebandStreamChanged() {
sp<ContentsChangedListener> listener;
{ // scope for the lock
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index d3f0070..7713ed2 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -33,6 +33,7 @@
static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8;
struct ContentsChangedListener: public FrameAvailableListener {
+ virtual void onBuffersReleased() = 0;
virtual void onSidebandStreamChanged() = 0;
};
@@ -89,6 +90,7 @@
FrameEventHistoryDelta* outDelta) override;
private:
+ virtual void onBuffersReleased();
virtual void onSidebandStreamChanged();
wp<ContentsChangedListener> mContentsChangedListener;
diff --git a/services/vr/vr_window_manager/Android.mk_disable b/services/vr/vr_window_manager/Android.mk
similarity index 96%
rename from services/vr/vr_window_manager/Android.mk_disable
rename to services/vr/vr_window_manager/Android.mk
index cc1db7b..47d9dcc 100644
--- a/services/vr/vr_window_manager/Android.mk_disable
+++ b/services/vr/vr_window_manager/Android.mk
@@ -100,7 +100,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(src)
-LOCAL_C_INCLUDES := hardware/qcom/display/msm8996/libgralloc
LOCAL_STATIC_LIBRARIES := $(static_libs)
LOCAL_SHARED_LIBRARIES := $(shared_libs)
LOCAL_SHARED_LIBRARIES += libgvr
@@ -117,7 +116,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(native_src)
-LOCAL_C_INCLUDES := hardware/qcom/display/msm8996/libgralloc
LOCAL_STATIC_LIBRARIES := $(static_libs) libvrwm_binder
LOCAL_SHARED_LIBRARIES := $(shared_libs)
LOCAL_SHARED_LIBRARIES += libgvr
diff --git a/services/vr/vr_window_manager/composer/Android.bp b/services/vr/vr_window_manager/composer/Android.bp
index 207d456..08c105c 100644
--- a/services/vr/vr_window_manager/composer/Android.bp
+++ b/services/vr/vr_window_manager/composer/Android.bp
@@ -2,46 +2,43 @@
"1.0",
]
-//cc_library_shared {
-// name: "libvrhwc",
-//
-// srcs: [
-// "impl/sync_timeline.cpp",
-// "impl/vr_composer_view.cpp",
-// "impl/vr_hwc.cpp",
-// "impl/vr_composer_client.cpp",
-// ],
-//
-// static_libs: [
-// "libhwcomposer-client",
-// ],
-//
-// shared_libs: [
-// "android.dvr.composer@1.0",
-// "android.hardware.graphics.composer@2.1",
-// "libbase",
-// "libcutils",
-// "libfmq",
-// "libhardware",
-// "libhidlbase",
-// "libhidltransport",
-// "liblog",
-// "libsync",
-// "libui",
-// "libutils",
-// ],
-//
-// export_include_dirs: ["."],
-//
-// include_dirs: [
-// // Access to software sync timeline.
-// "system/core/libsync",
-//
-// // Access to internal gralloc implementation.
-// "hardware/qcom/display/msm8996/libgralloc",
-// ],
-//
-// cflags: [
-// "-DLOG_TAG=\"vrhwc\"",
-// ],
-//}
+cc_library_shared {
+ name: "libvrhwc",
+
+ srcs: [
+ "impl/sync_timeline.cpp",
+ "impl/vr_composer_view.cpp",
+ "impl/vr_hwc.cpp",
+ "impl/vr_composer_client.cpp",
+ ],
+
+ static_libs: [
+ "libhwcomposer-client",
+ ],
+
+ shared_libs: [
+ "android.dvr.composer@1.0",
+ "android.hardware.graphics.composer@2.1",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libsync",
+ "libui",
+ "libutils",
+ ],
+
+ export_include_dirs: ["."],
+
+ include_dirs: [
+ // Access to software sync timeline.
+ "system/core/libsync",
+ ],
+
+ cflags: [
+ "-DLOG_TAG=\"vrhwc\"",
+ ],
+}
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
index 7e406a5..d7d0e5b 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -15,7 +15,6 @@
*/
#include "vr_hwc.h"
-#include <gralloc_priv.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
@@ -44,13 +43,28 @@
const Config kDefaultConfigId = 1;
sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
- // TODO(dnicoara): Fix this once gralloc1 is available.
- private_handle_t* private_handle = private_handle_t::dynamicCast(handle);
+ uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
+ uint64_t producer_usage = 0, consumer_usage = 0;
+ int32_t format = 0;
+
+ GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+ if (mapper.getDimensions(handle, &width, &height) ||
+ mapper.getStride(handle, &stride) ||
+ mapper.getFormat(handle, &format) ||
+ mapper.getProducerUsage(handle, &producer_usage) ||
+ mapper.getConsumerUsage(handle, &consumer_usage)) {
+ ALOGE("Failed to read handle properties");
+ return nullptr;
+ }
+
+ // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
+ // capability. Otherwise assume a count of 1.
+ mapper.getLayerCount(handle, &layer_count);
+
sp<GraphicBuffer> buffer = new GraphicBuffer(
- private_handle->width, private_handle->height, private_handle->format, 1,
- GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE,
- private_handle->width, native_handle_clone(handle), true);
- if (GraphicBufferMapper::get().registerBuffer(buffer.get()) != OK) {
+ width, height, format, layer_count, producer_usage, consumer_usage,
+ stride, native_handle_clone(handle), true);
+ if (mapper.registerBuffer(buffer.get()) != OK) {
ALOGE("Failed to register buffer");
return nullptr;
}
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
index 6b9487b..9450097 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -18,7 +18,8 @@
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <ComposerBase.h>
-#include <ui/GraphicBufferMapper.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
#include <mutex>
diff --git a/services/vr/vr_window_manager/hwc_callback.cpp b/services/vr/vr_window_manager/hwc_callback.cpp
index 5045790..12a76d8 100644
--- a/services/vr/vr_window_manager/hwc_callback.cpp
+++ b/services/vr/vr_window_manager/hwc_callback.cpp
@@ -1,10 +1,10 @@
#include "hwc_callback.h"
-#include <gralloc_priv.h>
#include <android-base/unique_fd.h>
#include <log/log.h>
#include <private/dvr/native_buffer.h>
#include <sync/sync.h>
+#include <ui/GraphicBufferMapper.h>
namespace android {
namespace dvr {
@@ -12,14 +12,28 @@
namespace {
sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
- // TODO(dnicoara): Fix this once gralloc1 is available.
- private_handle_t* private_handle = private_handle_t::dynamicCast(handle);
+ uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
+ uint64_t producer_usage = 0, consumer_usage = 0;
+ int32_t format = 0;
+
+ GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+ if (mapper.getDimensions(handle, &width, &height) ||
+ mapper.getStride(handle, &stride) ||
+ mapper.getFormat(handle, &format) ||
+ mapper.getProducerUsage(handle, &producer_usage) ||
+ mapper.getConsumerUsage(handle, &consumer_usage)) {
+ ALOGE("Failed to read handle properties");
+ return nullptr;
+ }
+
+ // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
+ // capability. Otherwise assume a count of 1.
+ mapper.getLayerCount(handle, &layer_count);
+
sp<GraphicBuffer> buffer = new GraphicBuffer(
- private_handle->width, private_handle->height, private_handle->format, 1,
- GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE |
- GraphicBuffer::USAGE_HW_2D | GraphicBuffer::USAGE_HW_RENDER,
- private_handle->width, native_handle_clone(handle), true);
- if (GraphicBufferMapper::get().registerBuffer(buffer.get()) != OK) {
+ width, height, format, layer_count, producer_usage, consumer_usage,
+ stride, native_handle_clone(handle), true);
+ if (mapper.registerBuffer(buffer.get()) != OK) {
ALOGE("Failed to register buffer");
return nullptr;
}