Merge "Fix boolean logic in SurfaceFlinger property read"
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 c6dfa37..baa6458 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -710,19 +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/am", "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/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h
index 30d7317..80ab7f3 100644
--- a/include/batteryservice/BatteryService.h
+++ b/include/batteryservice/BatteryService.h
@@ -26,13 +26,15 @@
#include "BatteryServiceConstants.h"
-// must be kept in sync with definitions in BatteryProperty.java
+// must be kept in sync with definitions in
+// frameworks/base/core/java/android/os/BatteryManager.java
enum {
- BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.CHARGE_COUNTER constant
- BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.CURRENT_NOW constant
- BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.CURRENT_AVG constant
- BATTERY_PROP_CAPACITY = 4, // equals BatteryProperty.CAPACITY constant
- BATTERY_PROP_ENERGY_COUNTER = 5, // equals BatteryProperty.ENERGY_COUNTER constant
+ BATTERY_PROP_CHARGE_COUNTER = 1, // equals BATTERY_PROPERTY_CHARGE_COUNTER
+ BATTERY_PROP_CURRENT_NOW = 2, // equals BATTERY_PROPERTY_CURRENT_NOW
+ BATTERY_PROP_CURRENT_AVG = 3, // equals BATTERY_PROPERTY_CURRENT_AVERAGE
+ BATTERY_PROP_CAPACITY = 4, // equals BATTERY_PROPERTY_CAPACITY
+ BATTERY_PROP_ENERGY_COUNTER = 5, // equals BATTERY_PROPERTY_ENERGY_COUNTER
+ BATTERY_PROP_BATTERY_STATUS = 6, // equals BATTERY_PROPERTY_BATTERY_STATUS
};
struct BatteryProperties {
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index ab676cc..55637a9 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -17,9 +17,6 @@
#ifndef ANDROID_GUI_BUFFERITEM_H
#define ANDROID_GUI_BUFFERITEM_H
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include <ui/FenceTime.h>
#include <ui/Rect.h>
#include <ui/Region.h>
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/gui/GraphicBufferAlloc.h b/include/gui/GraphicBufferAlloc.h
index b19a1ac..9e18907 100644
--- a/include/gui/GraphicBufferAlloc.h
+++ b/include/gui/GraphicBufferAlloc.h
@@ -35,8 +35,8 @@
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t layerCount,
- uint32_t usage, std::string requestorName,
- status_t* error) override;
+ uint64_t producerUsage, uint64_t consumerUsage,
+ std::string requestorName, status_t* error) override;
};
diff --git a/include/gui/IGraphicBufferAlloc.h b/include/gui/IGraphicBufferAlloc.h
index 2a7690a..1e578cc 100644
--- a/include/gui/IGraphicBufferAlloc.h
+++ b/include/gui/IGraphicBufferAlloc.h
@@ -38,14 +38,29 @@
/* Create a new GraphicBuffer for the client to use.
*/
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t layerCount, uint32_t usage,
- std::string requestorName, status_t* error) = 0;
+ PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+ uint64_t consumerUsage, std::string requestorName,
+ status_t* error) = 0;
sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t layerCount, uint32_t usage,
status_t* error) {
- return createGraphicBuffer(w, h, format, layerCount, usage, "<Unknown>",
- error);
+ return createGraphicBuffer(w, h, format, layerCount, usage,
+ usage, "<Unknown>", error);
+ }
+
+ sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+ PixelFormat format, uint32_t layerCount, uint32_t usage,
+ std::string requestorName, status_t* error) {
+ return createGraphicBuffer(w, h, format, layerCount, usage,
+ usage, requestorName, error);
+ }
+
+ sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+ PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+ uint64_t consumerUsage, status_t* error) {
+ return createGraphicBuffer(w, h, format, layerCount, producerUsage,
+ consumerUsage, "<Unknown>", error);
}
};
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 8af4d46..9870ba0 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -28,9 +28,7 @@
#include <binder/IInterface.h>
#include <ui/FrameStats.h>
-
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposerClient.h>
+#include <ui/PixelFormat.h>
#include <vector>
@@ -43,7 +41,9 @@
struct DisplayStatInfo;
class HdrCapabilities;
class IDisplayEventConnection;
-class IMemoryHeap;
+class IGraphicBufferAlloc;
+class IGraphicBufferProducer;
+class ISurfaceComposerClient;
class Rect;
enum class FrameEvent;
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 750e653..60203f7 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -17,17 +17,17 @@
#ifndef ANDROID_GUI_SURFACE_H
#define ANDROID_GUI_SURFACE_H
+#include <binder/Parcelable.h>
+
#include <gui/IGraphicBufferProducer.h>
-#include <gui/BufferQueue.h>
+#include <gui/BufferQueueDefs.h>
#include <ui/ANativeObjectBase.h>
#include <ui/Region.h>
-#include <binder/Parcelable.h>
-
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
struct ANativeWindow_Buffer;
@@ -251,7 +251,7 @@
virtual int attachBuffer(ANativeWindowBuffer*);
protected:
- enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
+ enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
void querySupportedTimestampsLocked() const;
diff --git a/include/private/gui/ComposerService.h b/include/private/gui/ComposerService.h
index ff2f9bf..50bd742 100644
--- a/include/private/gui/ComposerService.h
+++ b/include/private/gui/ComposerService.h
@@ -28,7 +28,6 @@
// ---------------------------------------------------------------------------
-class IMemoryHeap;
class ISurfaceComposer;
// ---------------------------------------------------------------------------
diff --git a/include/ui/Gralloc1.h b/include/ui/Gralloc1.h
index 64dacd7..640e29c 100644
--- a/include/ui/Gralloc1.h
+++ b/include/ui/Gralloc1.h
@@ -88,8 +88,6 @@
std::shared_ptr<Descriptor> createDescriptor();
- gralloc1_error_t getStride(buffer_handle_t buffer, uint32_t* outStride);
-
gralloc1_error_t allocate(
const std::vector<std::shared_ptr<const Descriptor>>& descriptors,
std::vector<buffer_handle_t>* outBuffers);
@@ -102,6 +100,19 @@
gralloc1_error_t release(buffer_handle_t buffer);
+ gralloc1_error_t getDimensions(buffer_handle_t buffer,
+ uint32_t* outWidth, uint32_t* outHeight);
+ gralloc1_error_t getFormat(buffer_handle_t buffer,
+ int32_t* outFormat);
+ gralloc1_error_t getLayerCount(buffer_handle_t buffer,
+ uint32_t* outLayerCount);
+ gralloc1_error_t getProducerUsage(buffer_handle_t buffer,
+ uint64_t* outProducerUsage);
+ gralloc1_error_t getConsumerUsage(buffer_handle_t buffer,
+ uint64_t* outConsumerUsage);
+ gralloc1_error_t getBackingStore(buffer_handle_t buffer,
+ uint64_t* outBackingStore);
+ gralloc1_error_t getStride(buffer_handle_t buffer, uint32_t* outStride);
gralloc1_error_t getNumFlexPlanes(buffer_handle_t buffer,
uint32_t* outNumPlanes);
diff --git a/include/ui/Gralloc1On0Adapter.h b/include/ui/Gralloc1On0Adapter.h
index 2508ce9..fcd2245 100644
--- a/include/ui/Gralloc1On0Adapter.h
+++ b/include/ui/Gralloc1On0Adapter.h
@@ -325,7 +325,7 @@
auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
auto error = callBufferFunction(device, bufferHandle,
&Buffer::getConsumerUsage, &usage);
- if (error != GRALLOC1_ERROR_NONE) {
+ if (error == GRALLOC1_ERROR_NONE) {
*outUsage = static_cast<uint64_t>(usage);
}
return error;
@@ -336,7 +336,7 @@
auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
auto error = callBufferFunction(device, bufferHandle,
&Buffer::getProducerUsage, &usage);
- if (error != GRALLOC1_ERROR_NONE) {
+ if (error == GRALLOC1_ERROR_NONE) {
*outUsage = static_cast<uint64_t>(usage);
}
return error;
diff --git a/include/ui/GrallocMapper.h b/include/ui/GrallocMapper.h
index f533dfb..5a23b68 100644
--- a/include/ui/GrallocMapper.h
+++ b/include/ui/GrallocMapper.h
@@ -45,17 +45,23 @@
Error retain(buffer_handle_t handle) const;
void release(buffer_handle_t handle) const;
+ Error getDimensions(buffer_handle_t handle,
+ uint32_t* outWidth, uint32_t* outHeight) const;
+ Error getFormat(buffer_handle_t handle, int32_t* outFormat) const;
+ Error getLayerCount(buffer_handle_t handle, uint32_t* outLayerCount) const;
+ Error getProducerUsage(buffer_handle_t handle,
+ uint64_t* outProducerUsage) const;
+ Error getConsumerUsage(buffer_handle_t handle,
+ uint64_t* outConsumerUsage) const;
+ Error getBackingStore(buffer_handle_t handle,
+ uint64_t* outBackingStore) const;
Error getStride(buffer_handle_t handle, uint32_t* outStride) const;
- Error lock(buffer_handle_t handle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const IMapper::Rect& accessRegion,
+ Error lock(buffer_handle_t handle, uint64_t producerUsage,
+ uint64_t consumerUsage, const IMapper::Rect& accessRegion,
int acquireFence, void** outData) const;
- Error lock(buffer_handle_t handle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
- const IMapper::Rect& accessRegion,
+ Error lock(buffer_handle_t handle, uint64_t producerUsage,
+ uint64_t consumerUsage, const IMapper::Rect& accessRegion,
int acquireFence, FlexLayout* outLayout) const;
int unlock(buffer_handle_t handle) const;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 1bbcee2..95ca0f3 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -81,11 +81,22 @@
uint32_t inLayerCount, uint32_t inUsage,
std::string requestorName = "<Unknown>");
+ // creates w * h buffer with a layer count using gralloc1
+ GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
+ uint32_t inLayerCount, uint64_t inProducerUsage,
+ uint64_t inConsumerUsage, std::string requestorName = "<Unknown>");
+
// create a buffer from an existing handle
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
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);
@@ -122,6 +133,8 @@
status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd);
status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr,
int fenceFd);
+ status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage,
+ const Rect& rect, void** vaddr, int fenceFd);
status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr,
int fenceFd);
status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect,
@@ -166,7 +179,8 @@
const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
- uint32_t inLayerCount, uint32_t inUsage, std::string requestorName);
+ uint32_t inLayerCount, uint64_t inProducerUsage,
+ uint64_t inConsumerUsage, std::string requestorName);
void free_handle();
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 16967d4..2ccc44b 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -65,8 +65,8 @@
static inline GraphicBufferAllocator& get() { return getInstance(); }
status_t allocate(uint32_t w, uint32_t h, PixelFormat format,
- uint32_t layerCount, uint32_t usage, buffer_handle_t* handle,
- uint32_t* stride, uint64_t graphicBufferId,
+ uint32_t layerCount, uint64_t producerUsage, uint64_t consumerUsage,
+ buffer_handle_t* handle, uint32_t* stride, uint64_t graphicBufferId,
std::string requestorName);
status_t free(buffer_handle_t handle);
@@ -81,7 +81,8 @@
uint32_t stride;
PixelFormat format;
uint32_t layerCount;
- uint32_t usage;
+ uint64_t producerUsage;
+ uint64_t consumerUsage;
size_t size;
std::string requestorName;
};
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index b6de1b2..8e93f72 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -44,6 +44,25 @@
status_t unregisterBuffer(buffer_handle_t handle);
+ status_t getDimensions(buffer_handle_t handle,
+ uint32_t* outWidth, uint32_t* outHeight) const;
+
+ status_t getFormat(buffer_handle_t handle, int32_t* outFormat) const;
+
+ status_t getLayerCount(buffer_handle_t handle,
+ uint32_t* outLayerCount) const;
+
+ status_t getProducerUsage(buffer_handle_t handle,
+ uint64_t* outProducerUsage) const;
+
+ status_t getConsumerUsage(buffer_handle_t handle,
+ uint64_t* outConsumerUsage) const;
+
+ status_t getBackingStore(buffer_handle_t handle,
+ uint64_t* outBackingStore) const;
+
+ status_t getStride(buffer_handle_t handle, uint32_t* outStride) const;
+
status_t lock(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, void** vaddr);
@@ -55,6 +74,10 @@
status_t lockAsync(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd);
+ status_t lockAsync(buffer_handle_t handle,
+ uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
+ void** vaddr, int fenceFd);
+
status_t lockAsyncYCbCr(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr,
int fenceFd);
diff --git a/include/gui/GraphicsEnv.h b/include/ui/GraphicsEnv.h
similarity index 94%
rename from include/gui/GraphicsEnv.h
rename to include/ui/GraphicsEnv.h
index 4c7366f..7817076 100644
--- a/include/gui/GraphicsEnv.h
+++ b/include/ui/GraphicsEnv.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_GUI_GRAPHICS_ENV_H
-#define ANDROID_GUI_GRAPHICS_ENV_H 1
+#ifndef ANDROID_UI_GRAPHICS_ENV_H
+#define ANDROID_UI_GRAPHICS_ENV_H 1
#include <string>
@@ -56,4 +56,4 @@
*/
extern "C" android_namespace_t* android_getDriverNamespace();
-#endif // ANDROID_GUI_GRAPHICS_ENV_H
+#endif // ANDROID_UI_GRAPHICS_ENV_H
diff --git a/include/ui/HdrCapabilities.h b/include/ui/HdrCapabilities.h
index a7cd5fb..925aa1b 100644
--- a/include/ui/HdrCapabilities.h
+++ b/include/ui/HdrCapabilities.h
@@ -17,11 +17,15 @@
#ifndef ANDROID_UI_HDR_CAPABILTIES_H
#define ANDROID_UI_HDR_CAPABILTIES_H
-#include <binder/Parcelable.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include <utils/Flattenable.h>
namespace android {
-class HdrCapabilities : public Parcelable
+class HdrCapabilities : public LightFlattenable<HdrCapabilities>
{
public:
HdrCapabilities(const std::vector<int32_t /*android_hdr_t*/>& types,
@@ -32,8 +36,8 @@
mMinLuminance(minLuminance) {}
// Make this move-constructable and move-assignable
- HdrCapabilities(HdrCapabilities&& other) = default;
- HdrCapabilities& operator=(HdrCapabilities&& other) = default;
+ HdrCapabilities(HdrCapabilities&& other);
+ HdrCapabilities& operator=(HdrCapabilities&& other);
HdrCapabilities()
: mSupportedHdrTypes(),
@@ -41,7 +45,7 @@
mMaxAverageLuminance(-1.0f),
mMinLuminance(-1.0f) {}
- virtual ~HdrCapabilities() = default;
+ ~HdrCapabilities();
const std::vector<int32_t /*android_hdr_t*/>& getSupportedHdrTypes() const {
return mSupportedHdrTypes;
@@ -50,9 +54,11 @@
float getDesiredMaxAverageLuminance() const { return mMaxAverageLuminance; }
float getDesiredMinLuminance() const { return mMinLuminance; }
- // Parcelable interface
- virtual status_t writeToParcel(Parcel* parcel) const override;
- virtual status_t readFromParcel(const Parcel* parcel) override;
+ // Flattenable protocol
+ bool isFixedSize() const { return false; }
+ size_t getFlattenedSize() const;
+ status_t flatten(void* buffer, size_t size) const;
+ status_t unflatten(void const* buffer, size_t size);
private:
std::vector<int32_t /*android_hdr_t*/> mSupportedHdrTypes;
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 3815bdc..cb17da4 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -77,7 +77,6 @@
"FrameTimestamps.cpp",
"GLConsumer.cpp",
"GraphicBufferAlloc.cpp",
- "GraphicsEnv.cpp",
"GuiConfig.cpp",
"IDisplayEventConnection.cpp",
"IGraphicBufferAlloc.cpp",
@@ -100,7 +99,6 @@
],
shared_libs: [
- "libnativeloader",
"libsync",
"libbinder",
"libcutils",
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/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index 30f5e53..f2d3677 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -33,9 +33,10 @@
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t layerCount,
- uint32_t usage, std::string requestorName, status_t* error) {
+ uint64_t producerUsage, uint64_t consumerUsage,
+ std::string requestorName, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
- width, height, format, layerCount, usage,
+ width, height, format, layerCount, producerUsage, consumerUsage,
std::move(requestorName)));
status_t err = graphicBuffer->initCheck();
*error = err;
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index a3d3b74..21a0dd5 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -46,14 +46,16 @@
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t layerCount,
- uint32_t usage, std::string requestorName, status_t* error) {
+ uint64_t producerUsage, uint64_t consumerUsage,
+ std::string requestorName, status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
data.writeUint32(width);
data.writeUint32(height);
data.writeInt32(static_cast<int32_t>(format));
data.writeUint32(layerCount);
- data.writeUint32(usage);
+ data.writeUint64(producerUsage);
+ data.writeUint64(consumerUsage);
if (requestorName.empty()) {
requestorName += "[PID ";
requestorName += std::to_string(getpid());
@@ -108,12 +110,14 @@
uint32_t height = data.readUint32();
PixelFormat format = static_cast<PixelFormat>(data.readInt32());
uint32_t layerCount = data.readUint32();
- uint32_t usage = data.readUint32();
+ uint64_t producerUsage = data.readUint64();
+ uint64_t consumerUsage = data.readUint64();
status_t error = NO_ERROR;
std::string requestorName;
data.readUtf8FromUtf16(&requestorName);
sp<GraphicBuffer> result = createGraphicBuffer(width, height,
- format, layerCount, usage, requestorName, &error);
+ format, layerCount, producerUsage, consumerUsage,
+ requestorName, &error);
reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 2a327da..06d1261 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -25,10 +25,11 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <gui/BitTube.h>
#include <gui/IDisplayEventConnection.h>
-#include <gui/ISurfaceComposer.h>
+#include <gui/IGraphicBufferAlloc.h>
#include <gui/IGraphicBufferProducer.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceComposerClient.h>
#include <private/gui/LayerState.h>
@@ -44,8 +45,6 @@
namespace android {
-class IDisplayEventConnection;
-
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
@@ -433,7 +432,7 @@
}
result = reply.readInt32();
if (result == NO_ERROR) {
- result = reply.readParcelable(outCapabilities);
+ result = reply.read(*outCapabilities);
}
return result;
}
@@ -754,7 +753,7 @@
result = getHdrCapabilities(display, &capabilities);
reply->writeInt32(result);
if (result == NO_ERROR) {
- reply->writeParcelable(capabilities);
+ reply->write(capabilities);
}
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c2ed91a..c663620 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -30,12 +30,11 @@
#include <ui/Region.h>
#include <ui/DisplayStatInfo.h>
+#include <gui/BufferItem.h>
#include <gui/IProducerListener.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/GLConsumer.h>
#include <gui/Surface.h>
+#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
namespace android {
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 4cd0d3a..cfe170d 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -55,6 +55,7 @@
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
+ "GraphicsEnv.cpp",
"HdrCapabilities.cpp",
"PixelFormat.cpp",
"Rect.cpp",
@@ -65,7 +66,7 @@
shared_libs: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
- "libbinder",
+ "libnativeloader",
"libcutils",
"libhardware",
"libhidlbase",
diff --git a/libs/ui/Gralloc1.cpp b/libs/ui/Gralloc1.cpp
index 367d1ce..0083f58 100644
--- a/libs/ui/Gralloc1.cpp
+++ b/libs/ui/Gralloc1.cpp
@@ -140,12 +140,6 @@
return descriptor;
}
-gralloc1_error_t Device::getStride(buffer_handle_t buffer, uint32_t* outStride)
-{
- int32_t intError = mFunctions.getStride(mDevice, buffer, outStride);
- return static_cast<gralloc1_error_t>(intError);
-}
-
static inline bool allocationSucceded(gralloc1_error_t error)
{
return error == GRALLOC1_ERROR_NONE || error == GRALLOC1_ERROR_NOT_SHARED;
@@ -225,6 +219,99 @@
return static_cast<gralloc1_error_t>(intError);
}
+gralloc1_error_t Device::getDimensions(buffer_handle_t buffer,
+ uint32_t* outWidth, uint32_t* outHeight)
+{
+ uint32_t width = 0;
+ uint32_t height = 0;
+ int32_t intError = mFunctions.getDimensions(mDevice, buffer, &width,
+ &height);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outWidth = width;
+ *outHeight = height;
+ }
+ return error;
+}
+
+gralloc1_error_t Device::getFormat(buffer_handle_t buffer,
+ int32_t* outFormat)
+{
+ int32_t format = 0;
+ int32_t intError = mFunctions.getFormat(mDevice, buffer, &format);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outFormat = format;
+ }
+ return error;
+}
+
+gralloc1_error_t Device::getLayerCount(buffer_handle_t buffer,
+ uint32_t* outLayerCount)
+{
+ if (hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
+ uint32_t layerCount = 0;
+ int32_t intError = mFunctions.getLayerCount(mDevice, buffer,
+ &layerCount);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outLayerCount = layerCount;
+ }
+ return error;
+ } else {
+ // Layered buffers are not supported on this device.
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+}
+
+gralloc1_error_t Device::getProducerUsage(buffer_handle_t buffer,
+ uint64_t* outProducerUsage)
+{
+ uint64_t usage = 0;
+ int32_t intError = mFunctions.getProducerUsage(mDevice, buffer, &usage);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outProducerUsage = usage;
+ }
+ return error;
+}
+
+gralloc1_error_t Device::getConsumerUsage(buffer_handle_t buffer,
+ uint64_t* outConsumerUsage)
+{
+ uint64_t usage = 0;
+ int32_t intError = mFunctions.getConsumerUsage(mDevice, buffer, &usage);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outConsumerUsage = usage;
+ }
+ return error;
+}
+
+gralloc1_error_t Device::getBackingStore(buffer_handle_t buffer,
+ uint64_t* outBackingStore)
+{
+ uint64_t store = 0;
+ int32_t intError = mFunctions.getBackingStore(mDevice, buffer, &store);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outBackingStore = store;
+ }
+ return error;
+}
+
+gralloc1_error_t Device::getStride(buffer_handle_t buffer,
+ uint32_t* outStride)
+{
+ uint32_t stride = 0;
+ int32_t intError = mFunctions.getStride(mDevice, buffer, &stride);
+ auto error = static_cast<gralloc1_error_t>(intError);
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outStride = stride;
+ }
+ return error;
+}
+
gralloc1_error_t Device::getNumFlexPlanes(buffer_handle_t buffer,
uint32_t* outNumPlanes)
{
@@ -244,7 +331,7 @@
const sp<Fence>& acquireFence)
{
ALOGV("Calling lock(%p)", buffer);
- return lockHelper(mFunctions.lock.pfn, buffer, producerUsage,
+ return lockHelper(mFunctions.lock, buffer, producerUsage,
consumerUsage, accessRegion, outData, acquireFence);
}
@@ -256,7 +343,7 @@
const sp<Fence>& acquireFence)
{
ALOGV("Calling lockFlex(%p)", buffer);
- return lockHelper(mFunctions.lockFlex.pfn, buffer, producerUsage,
+ return lockHelper(mFunctions.lockFlex, buffer, producerUsage,
consumerUsage, accessRegion, outData, acquireFence);
}
@@ -268,7 +355,7 @@
const sp<Fence>& acquireFence)
{
ALOGV("Calling lockYCbCr(%p)", buffer);
- return lockHelper(mFunctions.lockYCbCr.pfn, buffer, producerUsage,
+ return lockHelper(mFunctions.lockYCbCr, buffer, producerUsage,
consumerUsage, accessRegion, outData, acquireFence);
}
diff --git a/libs/ui/GrallocMapper.cpp b/libs/ui/GrallocMapper.cpp
index 7ee01ad..b9e9040 100644
--- a/libs/ui/GrallocMapper.cpp
+++ b/libs/ui/GrallocMapper.cpp
@@ -51,6 +51,115 @@
"release(%p) failed with %d", handle, error);
}
+Error Mapper::getDimensions(buffer_handle_t handle,
+ uint32_t* outWidth, uint32_t* outHeight) const
+{
+ Error error = kDefaultError;
+ mMapper->getDimensions(handle,
+ [&](const auto& tmpError, const auto& tmpWidth,
+ const auto& tmpHeight)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outWidth = tmpWidth;
+ *outHeight = tmpHeight;
+ });
+
+ return error;
+}
+
+Error Mapper::getFormat(buffer_handle_t handle, int32_t* outFormat) const
+{
+ Error error = kDefaultError;
+ mMapper->getFormat(handle,
+ [&](const auto& tmpError, const auto& tmpFormat)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outFormat = static_cast<int32_t>(tmpFormat);
+ });
+
+ return error;
+}
+
+Error Mapper::getLayerCount(buffer_handle_t handle,
+ uint32_t* outLayerCount) const
+{
+ Error error = kDefaultError;
+ mMapper->getLayerCount(handle,
+ [&](const auto& tmpError, const auto& tmpLayerCount)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outLayerCount = tmpLayerCount;
+ });
+
+ return error;
+}
+
+Error Mapper::getProducerUsage(buffer_handle_t handle,
+ uint64_t* outProducerUsage) const
+{
+ Error error = kDefaultError;
+ mMapper->getProducerUsageMask(handle,
+ [&](const auto& tmpError, const auto& tmpProducerUsage)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outProducerUsage = tmpProducerUsage;
+ });
+
+ return error;
+}
+
+Error Mapper::getConsumerUsage(buffer_handle_t handle,
+ uint64_t* outConsumerUsage) const
+{
+ Error error = kDefaultError;
+ mMapper->getConsumerUsageMask(handle,
+ [&](const auto& tmpError, const auto& tmpConsumerUsage)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outConsumerUsage = tmpConsumerUsage;
+ });
+
+ return error;
+}
+
+Error Mapper::getBackingStore(buffer_handle_t handle,
+ uint64_t* outBackingStore) const
+{
+ Error error = kDefaultError;
+ mMapper->getBackingStore(handle,
+ [&](const auto& tmpError, const auto& tmpStore)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outBackingStore = tmpStore;
+ });
+
+ return error;
+}
+
Error Mapper::getStride(buffer_handle_t handle, uint32_t* outStride) const
{
Error error = kDefaultError;
@@ -69,8 +178,8 @@
}
Error Mapper::lock(buffer_handle_t handle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
+ uint64_t producerUsage,
+ uint64_t consumerUsage,
const IMapper::Rect& accessRegion,
int acquireFence, void** outData) const
{
@@ -84,7 +193,7 @@
}
Error error = kDefaultError;
- mMapper->lock(handle, producerUsageMask, consumerUsageMask,
+ mMapper->lock(handle, producerUsage, consumerUsage,
accessRegion, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpData)
{
@@ -104,8 +213,8 @@
}
Error Mapper::lock(buffer_handle_t handle,
- uint64_t producerUsageMask,
- uint64_t consumerUsageMask,
+ uint64_t producerUsage,
+ uint64_t consumerUsage,
const IMapper::Rect& accessRegion,
int acquireFence, FlexLayout* outLayout) const
{
@@ -119,7 +228,7 @@
}
Error error = kDefaultError;
- mMapper->lockFlex(handle, producerUsageMask, consumerUsageMask,
+ mMapper->lockFlex(handle, producerUsage, consumerUsage,
accessRegion, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpLayout)
{
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 07164a4..5ef95ec 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -67,13 +67,13 @@
layerCount =
usage = 0;
handle = NULL;
- mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage,
+ mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
std::move(requestorName));
}
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
- PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
- std::string requestorName)
+ PixelFormat inFormat, uint32_t inLayerCount, uint64_t producerUsage,
+ uint64_t consumerUsage, std::string requestorName)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
{
@@ -84,8 +84,8 @@
layerCount =
usage = 0;
handle = NULL;
- mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage,
- std::move(requestorName));
+ mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
+ producerUsage, consumerUsage, std::move(requestorName));
}
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
@@ -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()),
@@ -177,7 +195,7 @@
allocator.free(handle);
handle = 0;
}
- return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage,
+ return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage,
"[Reallocation]");
}
@@ -193,19 +211,20 @@
}
status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
- PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
- std::string requestorName)
+ PixelFormat inFormat, uint32_t inLayerCount, uint64_t inProducerUsage,
+ uint64_t inConsumerUsage, std::string requestorName)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
uint32_t outStride = 0;
status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
- inUsage, &handle, &outStride, mId, std::move(requestorName));
+ inProducerUsage, inConsumerUsage, &handle, &outStride, mId,
+ std::move(requestorName));
if (err == NO_ERROR) {
width = static_cast<int>(inWidth);
height = static_cast<int>(inHeight);
format = inFormat;
layerCount = inLayerCount;
- usage = static_cast<int>(inUsage);
+ usage = static_cast<int>(inProducerUsage | inConsumerUsage);
stride = static_cast<int>(outStride);
}
return err;
@@ -268,6 +287,12 @@
status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect,
void** vaddr, int fenceFd)
{
+ return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd);
+}
+
+status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage,
+ uint64_t inConsumerUsage, const Rect& rect, void** vaddr, int fenceFd)
+{
if (rect.left < 0 || rect.right > width ||
rect.top < 0 || rect.bottom > height) {
ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
@@ -275,8 +300,8 @@
width, height);
return BAD_VALUE;
}
- status_t res = getBufferMapper().lockAsync(handle, inUsage, rect, vaddr,
- fenceFd);
+ status_t res = getBufferMapper().lockAsync(handle, inProducerUsage,
+ inConsumerUsage, rect, vaddr, fenceFd);
return res;
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 07ad4c1..b14110e 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -63,15 +63,19 @@
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
if (rec.size) {
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%08x | %s\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64
+ ", 0x%" PRIx64 " | %s\n",
list.keyAt(i), rec.size/1024.0,
rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
- rec.usage, rec.requestorName.c_str());
+ rec.producerUsage, rec.consumerUsage,
+ rec.requestorName.c_str());
} else {
- snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%08x | %s\n",
+ snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64
+ ", 0x%" PRIx64 " | %s\n",
list.keyAt(i),
rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
- rec.usage, rec.requestorName.c_str());
+ rec.producerUsage, rec.consumerUsage,
+ rec.requestorName.c_str());
}
result.append(buffer);
total += rec.size;
@@ -102,7 +106,8 @@
public:
HalBuffer(const Gralloc2::Allocator* allocator,
uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount, uint32_t usage)
+ PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+ uint64_t consumerUsage)
: mAllocator(allocator), mBufferValid(false)
{
Gralloc2::IAllocatorClient::BufferDescriptorInfo info = {};
@@ -110,14 +115,16 @@
info.height = height;
info.format = static_cast<Gralloc2::PixelFormat>(format);
info.layerCount = layerCount;
- info.producerUsageMask = usage;
- info.consumerUsageMask = usage;
+ info.producerUsageMask = producerUsage;
+ info.consumerUsageMask = consumerUsage;
Gralloc2::BufferDescriptor descriptor;
auto error = mAllocator->createBufferDescriptor(info, &descriptor);
if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to create desc (%u x %u) layerCount %u format %d usage %u: %d",
- width, height, layerCount, format, usage, error);
+ ALOGE("Failed to create desc (%u x %u) layerCount %u format %d producerUsage %" PRIx64
+ " consumerUsage %" PRIx64 ": %d",
+ width, height, layerCount, format, producerUsage,
+ consumerUsage, error);
return;
}
@@ -127,8 +134,10 @@
}
if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to allocate (%u x %u) layerCount %u format %d usage %u: %d",
- width, height, layerCount, format, usage, error);
+ ALOGE("Failed to allocate (%u x %u) layerCount %u format %d producerUsage %" PRIx64
+ " consumerUsage %" PRIx64 ": %d",
+ width, height, layerCount, format, producerUsage,
+ consumerUsage, error);
mAllocator->destroyBufferDescriptor(descriptor);
return;
}
@@ -195,9 +204,9 @@
} // namespace
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount, uint32_t usage,
- buffer_handle_t* handle, uint32_t* stride, uint64_t graphicBufferId,
- std::string requestorName)
+ PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+ uint64_t consumerUsage, buffer_handle_t* handle, uint32_t* stride,
+ uint64_t graphicBufferId, std::string requestorName)
{
ATRACE_CALL();
@@ -210,13 +219,10 @@
if (layerCount < 1)
layerCount = 1;
- // Filter out any usage bits that should not be passed to the gralloc module
- usage &= GRALLOC_USAGE_ALLOC_MASK;
-
gralloc1_error_t error;
if (mAllocator->valid()) {
HalBuffer buffer(mAllocator.get(), width, height, format, layerCount,
- usage);
+ producerUsage, consumerUsage);
if (!buffer.exportHandle(mMapper, handle, stride)) {
return NO_MEMORY;
}
@@ -247,22 +253,26 @@
return BAD_VALUE;
}
error = descriptor->setProducerUsage(
- static_cast<gralloc1_producer_usage_t>(usage));
+ static_cast<gralloc1_producer_usage_t>(producerUsage));
if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to set producer usage to %u: %d", usage, error);
+ ALOGE("Failed to set producer usage to %" PRIx64 ": %d",
+ producerUsage, error);
return BAD_VALUE;
}
error = descriptor->setConsumerUsage(
- static_cast<gralloc1_consumer_usage_t>(usage));
+ static_cast<gralloc1_consumer_usage_t>(consumerUsage));
if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to set consumer usage to %u: %d", usage, error);
+ ALOGE("Failed to set consumer usage to %" PRIx64 ": %d",
+ consumerUsage, error);
return BAD_VALUE;
}
error = mDevice->allocate(descriptor, graphicBufferId, handle);
if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to allocate (%u x %u) layerCount %u format %d usage %u: %d",
- width, height, layerCount, format, usage, error);
+ ALOGE("Failed to allocate (%u x %u) layerCount %u format %d "
+ "producerUsage %" PRIx64 " consumerUsage %" PRIx64 ": %d",
+ width, height, layerCount, format, producerUsage,
+ consumerUsage, error);
return NO_MEMORY;
}
@@ -282,7 +292,8 @@
rec.stride = *stride;
rec.format = format;
rec.layerCount = layerCount;
- rec.usage = usage;
+ rec.producerUsage = producerUsage;
+ rec.consumerUsage = consumerUsage;
rec.size = static_cast<size_t>(height * (*stride) * bpp);
rec.requestorName = std::move(requestorName);
list.add(*handle, rec);
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 1ff934b..b0ed2df 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -117,6 +117,140 @@
return outRect;
}
+
+status_t GraphicBufferMapper::getDimensions(buffer_handle_t handle,
+ uint32_t* outWidth, uint32_t* outHeight) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getDimensions(handle, outWidth, outHeight);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getDimensions(handle, outWidth, outHeight);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getDimensions(%p, ...): failed %d",
+ handle, error);
+
+ return error;
+}
+
+status_t GraphicBufferMapper::getFormat(buffer_handle_t handle,
+ int32_t* outFormat) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getFormat(handle, outFormat);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getFormat(handle, outFormat);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getFormat(%p, ...): failed %d",
+ handle, error);
+
+ return error;
+}
+
+status_t GraphicBufferMapper::getLayerCount(buffer_handle_t handle,
+ uint32_t* outLayerCount) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getLayerCount(handle, outLayerCount);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getLayerCount(handle, outLayerCount);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getLayerCount(%p, ...): failed %d",
+ handle, error);
+
+ return error;
+}
+
+status_t GraphicBufferMapper::getProducerUsage(buffer_handle_t handle,
+ uint64_t* outProducerUsage) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getProducerUsage(handle, outProducerUsage);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getProducerUsage(handle, outProducerUsage);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+ "getProducerUsage(%p, ...): failed %d", handle, error);
+
+ return error;
+}
+
+status_t GraphicBufferMapper::getConsumerUsage(buffer_handle_t handle,
+ uint64_t* outConsumerUsage) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getConsumerUsage(handle, outConsumerUsage);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getConsumerUsage(handle, outConsumerUsage);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+ "getConsumerUsage(%p, ...): failed %d", handle, error);
+
+ return error;
+}
+
+status_t GraphicBufferMapper::getBackingStore(buffer_handle_t handle,
+ uint64_t* outBackingStore) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getBackingStore(handle, outBackingStore);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getBackingStore(handle, outBackingStore);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+ "getBackingStore(%p, ...): failed %d", handle, error);
+
+ return error;
+}
+
+status_t GraphicBufferMapper::getStride(buffer_handle_t handle,
+ uint32_t* outStride) const
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->getStride(handle, outStride);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->getStride(handle, outStride);
+ }
+
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getStride(%p, ...): failed %d",
+ handle, error);
+
+ return error;
+}
+
status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
const Rect& bounds, void** vaddr)
{
@@ -143,6 +277,13 @@
status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
{
+ return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd);
+}
+
+status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
+ uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
+ void** vaddr, int fenceFd)
+{
ATRACE_CALL();
gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
@@ -151,12 +292,13 @@
const Gralloc2::IMapper::Rect& accessRect =
*reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
error = static_cast<gralloc1_error_t>(mMapper->lock(
- handle, usage, usage, accessRect, fenceFd, vaddr));
+ handle, producerUsage, consumerUsage, accessRect,
+ fenceFd, vaddr));
} else {
sp<Fence> fence = new Fence(fenceFd);
error = mDevice->lock(handle,
- static_cast<gralloc1_producer_usage_t>(usage),
- static_cast<gralloc1_consumer_usage_t>(usage),
+ static_cast<gralloc1_producer_usage_t>(producerUsage),
+ static_cast<gralloc1_consumer_usage_t>(consumerUsage),
&accessRegion, vaddr, fence);
}
diff --git a/libs/gui/GraphicsEnv.cpp b/libs/ui/GraphicsEnv.cpp
similarity index 98%
rename from libs/gui/GraphicsEnv.cpp
rename to libs/ui/GraphicsEnv.cpp
index 68f0f98..1d20424 100644
--- a/libs/gui/GraphicsEnv.cpp
+++ b/libs/ui/GraphicsEnv.cpp
@@ -16,7 +16,7 @@
//#define LOG_NDEBUG 1
#define LOG_TAG "GraphicsEnv"
-#include <gui/GraphicsEnv.h>
+#include <ui/GraphicsEnv.h>
#include <mutex>
diff --git a/libs/ui/HdrCapabilities.cpp b/libs/ui/HdrCapabilities.cpp
index 511f68a..39adc5e 100644
--- a/libs/ui/HdrCapabilities.cpp
+++ b/libs/ui/HdrCapabilities.cpp
@@ -16,44 +16,76 @@
#include <ui/HdrCapabilities.h>
-#include <binder/Parcel.h>
-
namespace android {
-status_t HdrCapabilities::writeToParcel(Parcel* parcel) const
-{
- status_t result = parcel->writeInt32Vector(mSupportedHdrTypes);
- if (result != OK) {
- return result;
- }
- result = parcel->writeFloat(mMaxLuminance);
- if (result != OK) {
- return result;
- }
- result = parcel->writeFloat(mMaxAverageLuminance);
- if (result != OK) {
- return result;
- }
- result = parcel->writeFloat(mMinLuminance);
- return result;
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundefined-reinterpret-cast"
+#endif
+
+HdrCapabilities::~HdrCapabilities() = default;
+HdrCapabilities::HdrCapabilities(HdrCapabilities&& other) = default;
+HdrCapabilities& HdrCapabilities::operator=(HdrCapabilities&& other) = default;
+
+
+size_t HdrCapabilities::getFlattenedSize() const {
+ return sizeof(mMaxLuminance) +
+ sizeof(mMaxAverageLuminance) +
+ sizeof(mMinLuminance) +
+ sizeof(int32_t) +
+ mSupportedHdrTypes.size() * sizeof(int32_t);
}
-status_t HdrCapabilities::readFromParcel(const Parcel* parcel)
-{
- status_t result = parcel->readInt32Vector(&mSupportedHdrTypes);
- if (result != OK) {
- return result;
+status_t HdrCapabilities::flatten(void* buffer, size_t size) const {
+
+ if (size < getFlattenedSize()) {
+ return NO_MEMORY;
}
- result = parcel->readFloat(&mMaxLuminance);
- if (result != OK) {
- return result;
+
+ int32_t* const buf = static_cast<int32_t*>(buffer);
+ reinterpret_cast<float&>(buf[0]) = mMaxLuminance;
+ reinterpret_cast<float&>(buf[1]) = mMaxAverageLuminance;
+ reinterpret_cast<float&>(buf[2]) = mMinLuminance;
+ buf[3] = static_cast<int32_t>(mSupportedHdrTypes.size());
+ for (size_t i = 0, c = mSupportedHdrTypes.size(); i < c; ++i) {
+ buf[4 + i] = mSupportedHdrTypes[i];
}
- result = parcel->readFloat(&mMaxAverageLuminance);
- if (result != OK) {
- return result;
- }
- result = parcel->readFloat(&mMinLuminance);
- return result;
+ return NO_ERROR;
}
+status_t HdrCapabilities::unflatten(void const* buffer, size_t size) {
+
+ size_t minSize = sizeof(mMaxLuminance) +
+ sizeof(mMaxAverageLuminance) +
+ sizeof(mMinLuminance) +
+ sizeof(int32_t);
+
+ if (size < minSize) {
+ return NO_MEMORY;
+ }
+
+ int32_t const * const buf = static_cast<int32_t const *>(buffer);
+ const size_t itemCount = size_t(buf[3]);
+
+ // check the buffer is large enough
+ if (size < minSize + itemCount * sizeof(int32_t)) {
+ return BAD_VALUE;
+ }
+
+ mMaxLuminance = reinterpret_cast<float const&>(buf[0]);
+ mMaxAverageLuminance = reinterpret_cast<float const&>(buf[1]);
+ mMinLuminance = reinterpret_cast<float const&>(buf[2]);
+ if (itemCount) {
+ mSupportedHdrTypes.reserve(itemCount);
+ for (size_t i = 0; i < itemCount; ++i) {
+ mSupportedHdrTypes[i] = buf[4 + i];
+ }
+ }
+ return NO_ERROR;
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
} // namespace android
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/libgvr/Android.mk b/libs/vr/libgvr/Android.mk
index be78605..0daf2ea 100644
--- a/libs/vr/libgvr/Android.mk
+++ b/libs/vr/libgvr/Android.mk
@@ -19,10 +19,9 @@
# Java platform library for the system implementation of the GVR API.
include $(CLEAR_VARS)
-LOCAL_MODULE := gvr_platform
-LOCAL_MODULE_STEM := com.google.vr.gvr.platform
+LOCAL_MODULE := com.google.vr.gvr.platform
LOCAL_REQUIRED_MODULES := libgvr_system_loader libgvr_system
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
include $(BUILD_JAVA_LIBRARY)
# Library to perform dlopen on the actual platform library.
diff --git a/libs/vr/libgvr/java/com/google/vr/gvr/platform/Loader.java b/libs/vr/libgvr/java/com/google/vr/gvr/platform/Loader.java
index 5c5cc62..381175c 100644
--- a/libs/vr/libgvr/java/com/google/vr/gvr/platform/Loader.java
+++ b/libs/vr/libgvr/java/com/google/vr/gvr/platform/Loader.java
@@ -1,32 +1,38 @@
package com.google.vr.gvr.platform;
+import android.os.SystemProperties;
+
/**
* Auxiliary class to load the system implementation of the GVR API.
+ * @hide
*/
public class Loader {
- /**
- * Opens a shared library containing the system implementation for the GVR
- * API and returns the handle to it.
- *
- * @return A Long object describing the handle returned by dlopen.
- */
- public static Long loadLibrary() {
- // Note: we cannot safely do caller verifications here, so instead we do
- // them in the service side. This means that private API symbols will be
- // visible to any app adding the appropriate <uses-library> in their
- // manifest, but any requests to such APIs will fail if not done from a
- // trusted package like VrCore.
- //
- // Trusted packages are defined by (package name, signature) pairs in within
- // a system service, and both must match.
+ private static final String VR_MODE_BOOT = "ro.boot.vr";
- // Load a thin JNI library that runs dlopen on request.
- System.loadLibrary("gvr_system_loader");
+ /**
+ * Opens a shared library containing the system implementation for the GVR API and returns the
+ * handle to it.
+ *
+ * @return A Long object describing the handle returned by dlopen.
+ */
+ public static Long loadLibrary() {
+ // Note: caller verifications cannot be safely done here. Any app can find and use this API.
+ // Any sensitive functions must have appropriate checks on the service side.
- // Performs dlopen on the library and returns the handle.
- return nativeLoadLibrary("libgvr_system.so");
- }
+ // Load a thin JNI library that runs dlopen on request.
+ System.loadLibrary("gvr_system_loader");
- private static native long nativeLoadLibrary(String library);
+ // Performs dlopen on the library and returns the handle.
+ return nativeLoadLibrary("libgvr_system.so");
+ }
+
+ /**
+ * Returns true if this device boots directly in VR mode.
+ */
+ public static boolean getVrBoot() {
+ return SystemProperties.getBoolean(VR_MODE_BOOT, false);
+ }
+
+ private static native long nativeLoadLibrary(String library);
}
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/display_surface.cpp b/libs/vr/libvrflinger/display_surface.cpp
index e1729f8..7c821bf 100644
--- a/libs/vr/libvrflinger/display_surface.cpp
+++ b/libs/vr/libvrflinger/display_surface.cpp
@@ -381,6 +381,15 @@
ATRACE_NAME("DisplaySurface::OnPostConsumer");
std::lock_guard<std::mutex> autolock(lock_);
+ if (!IsVisible()) {
+ ALOGD_IF(TRACE,
+ "DisplaySurface::OnPostConsumer: Discarding buffer_id=%d on "
+ "invisible surface.",
+ consumer->id());
+ consumer->Discard();
+ return;
+ }
+
if (posted_buffers_.IsFull()) {
ALOGE("Error: posted buffers full, overwriting");
posted_buffers_.PopBack();
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index cc08209..5253b26 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -104,11 +104,10 @@
display_transform_(HWC_TRANSFORM_NONE),
display_surfaces_updated_(false),
hardware_layers_need_update_(false),
- display_on_(false),
active_layer_count_(0),
gpu_layer_(nullptr),
+ post_thread_state_(PostThreadState::kPaused),
terminate_post_thread_event_fd_(-1),
- pause_post_thread_(true),
backlight_brightness_fd_(-1),
primary_display_vsync_event_fd_(-1),
primary_display_wait_pp_fd_(-1),
@@ -124,19 +123,17 @@
}
HardwareComposer::~HardwareComposer(void) {
- if (!IsSuspended()) {
- Suspend();
- }
+ Suspend();
}
bool HardwareComposer::Resume() {
- std::lock_guard<std::mutex> autolock(layer_mutex_);
-
- if (!IsSuspended()) {
- ALOGE("HardwareComposer::Resume: HardwareComposer is already running.");
+ std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
+ if (post_thread_state_ == PostThreadState::kRunning) {
return false;
}
+ std::lock_guard<std::mutex> layer_lock(layer_mutex_);
+
int32_t ret = HWC2_ERROR_NONE;
static const uint32_t attributes[] = {
@@ -250,39 +247,49 @@
pose_client_ = dvrPoseCreate();
ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
- // Variables used to control the post thread state
- pause_post_thread_ = false;
- terminate_post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-
+ terminate_post_thread_event_fd_.Reset(
+ eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
LOG_ALWAYS_FATAL_IF(
!terminate_post_thread_event_fd_,
"HardwareComposer: Failed to create terminate PostThread event fd : %s",
strerror(errno));
+ post_thread_state_ = PostThreadState::kRunning;
+ post_thread_state_cond_var_.notify_all();
+
// If get_id() is the default thread::id object, it has not been created yet
if (post_thread_.get_id() == std::thread::id()) {
post_thread_ = std::thread(&HardwareComposer::PostThread, this);
} else {
UpdateDisplayState();
- thread_pause_semaphore_.notify_one();
}
return true;
}
bool HardwareComposer::Suspend() {
- // Wait for any pending layer operations to finish
- std::unique_lock<std::mutex> layer_lock(layer_mutex_);
-
- if (IsSuspended()) {
- ALOGE("HardwareComposer::Suspend: HardwareComposer is already suspended.");
+ std::unique_lock<std::mutex> post_thread_lock(post_thread_state_mutex_);
+ if (post_thread_state_ == PostThreadState::kPaused) {
return false;
}
- PausePostThread();
+ post_thread_state_ = PostThreadState::kPauseRequested;
+
+ int error = eventfd_write(terminate_post_thread_event_fd_.Get(), 1);
+ ALOGE_IF(error,
+ "HardwareComposer::Suspend: could not write post "
+ "thread termination event fd : %d",
+ error);
+
+ post_thread_state_cond_var_.wait(
+ post_thread_lock,
+ [this] { return post_thread_state_ == PostThreadState::kPaused; });
+ terminate_post_thread_event_fd_.Close();
+
+ // Wait for any pending layer operations to finish
+ std::lock_guard<std::mutex> layer_lock(layer_mutex_);
EnableVsync(false);
- SetPowerMode(HWC_DISPLAY_PRIMARY, HWC2_POWER_MODE_OFF);
backlight_brightness_fd_.Close();
primary_display_vsync_event_fd_.Close();
@@ -308,19 +315,6 @@
return true;
}
-void HardwareComposer::PausePostThread() {
- pause_post_thread_ = true;
-
- int error = eventfd_write(terminate_post_thread_event_fd_.Get(), 1);
- ALOGE_IF(error,
- "HardwareComposer::PausePostThread: could not write post "
- "thread termination event fd : %d",
- error);
-
- std::unique_lock<std::mutex> wait_for_thread(thread_pause_mutex_);
- terminate_post_thread_event_fd_.Close();
-}
-
DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
vec2i screen_size(display_metrics_.width, display_metrics_.height);
DisplayOrientation orientation =
@@ -382,18 +376,6 @@
return error;
}
-int32_t HardwareComposer::SetPowerMode(hwc2_display_t display,
- hwc2_power_mode_t mode) {
- if (mode == HWC2_POWER_MODE_OFF) {
- EnableVsync(false);
- }
-
- display_on_ = mode != HWC2_POWER_MODE_OFF;
-
- return (int32_t)hwc2_hidl_->setPowerMode(
- display, (Hwc2::IComposerClient::PowerMode)mode);
-}
-
int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
hwc2_config_t config,
hwc2_attribute_t attribute,
@@ -556,31 +538,23 @@
const bool has_display_surfaces = display_surfaces_.size() > 0;
if (has_display_surfaces) {
- int32_t ret = SetPowerMode(HWC_DISPLAY_PRIMARY, HWC2_POWER_MODE_ON);
-
- ALOGE_IF(ret, "HardwareComposer: Could not set power mode; ret=%d", ret);
-
EnableVsync(true);
}
+
// TODO(skiazyk): We need to do something about accessing this directly,
// supposedly there is a backlight service on the way.
SetBacklightBrightness(255);
- if (!display_on_ && has_display_surfaces) {
- const int error = ReadVSyncTimestamp(&last_vsync_timestamp_);
- ALOGE_IF(error < 0,
- "HardwareComposer::SetDisplaySurfaces: Failed to read vsync "
- "timestamp: %s",
- strerror(-error));
- }
-
// Trigger target-specific performance mode change.
- property_set(kDvrPerformanceProperty, display_on_ ? "performance" : "idle");
+ property_set(kDvrPerformanceProperty, has_display_surfaces ? "performance" : "idle");
}
int HardwareComposer::SetDisplaySurfaces(
std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
- std::lock_guard<std::mutex> autolock(layer_mutex_);
+ // The double lock is necessary because we access both the display surfaces
+ // and post_thread_state_.
+ std::lock_guard<std::mutex> post_thread_state_lock(post_thread_state_mutex_);
+ std::lock_guard<std::mutex> layer_lock(layer_mutex_);
ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
surfaces.size());
@@ -626,7 +600,7 @@
// TODO(skiazyk): fix this so that it is handled seamlessly with dormant/non-
// dormant state.
- if (!IsSuspended()) {
+ if (post_thread_state_ == PostThreadState::kRunning) {
UpdateDisplayState();
}
@@ -726,7 +700,8 @@
// Blocks until the next vsync event is signaled by the display driver.
// TODO(eieio): This is pretty driver specific, this should be moved to a
// separate class eventually.
-int HardwareComposer::BlockUntilVSync() {
+int HardwareComposer::BlockUntilVSync(/*out*/ bool* suspend_requested) {
+ *suspend_requested = false;
const int event_fd = primary_display_vsync_event_fd_.Get();
pollfd pfd[2] = {
{
@@ -751,6 +726,8 @@
strerror(error), error);
} while (ret < 0 && error == EINTR);
+ if (ret >= 0 && pfd[1].revents != 0)
+ *suspend_requested = true;
return ret < 0 ? -error : 0;
}
@@ -773,15 +750,11 @@
if (error == -EAGAIN) {
// Vsync was turned off, wait for the next vsync event.
- error = BlockUntilVSync();
- if (error < 0)
+ bool suspend_requested = false;
+ error = BlockUntilVSync(&suspend_requested);
+ if (error < 0 || suspend_requested)
return error;
- // If a request to pause the post thread was given, exit immediately
- if (IsSuspended()) {
- return 0;
- }
-
// Try again to get the timestamp for this new vsync interval.
continue;
}
@@ -802,14 +775,10 @@
if (distance_to_vsync_est > threshold_ns) {
// Wait for vsync event notification.
- error = BlockUntilVSync();
- if (error < 0)
+ bool suspend_requested = false;
+ error = BlockUntilVSync(&suspend_requested);
+ if (error < 0 || suspend_requested)
return error;
-
- // Again, exit immediately if the thread was requested to pause
- if (IsSuspended()) {
- return 0;
- }
} else {
// Sleep for a short time before retrying.
std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -848,8 +817,6 @@
// NOLINTNEXTLINE(runtime/int)
prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("PostThread"), 0, 0, 0);
- std::unique_lock<std::mutex> thread_lock(thread_pause_mutex_);
-
// Set the scheduler to SCHED_FIFO with high priority.
int error = dvrSetSchedulerClass(0, "graphics:high");
LOG_ALWAYS_FATAL_IF(
@@ -903,12 +870,19 @@
while (1) {
ATRACE_NAME("HardwareComposer::PostThread");
- while (IsSuspended()) {
- ALOGI("HardwareComposer::PostThread: Post thread pause requested.");
- thread_pause_semaphore_.wait(thread_lock);
- // The layers will need to be updated since they were deleted previously
- display_surfaces_updated_ = true;
- hardware_layers_need_update_ = true;
+ {
+ std::unique_lock<std::mutex> post_thread_lock(post_thread_state_mutex_);
+ if (post_thread_state_ == PostThreadState::kPauseRequested) {
+ ALOGI("HardwareComposer::PostThread: Post thread pause requested.");
+ post_thread_state_ = PostThreadState::kPaused;
+ post_thread_state_cond_var_.notify_all();
+ post_thread_state_cond_var_.wait(
+ post_thread_lock,
+ [this] { return post_thread_state_ == PostThreadState::kRunning; });
+ // The layers will need to be updated since they were deleted previously
+ display_surfaces_updated_ = true;
+ hardware_layers_need_update_ = true;
+ }
}
int64_t vsync_timestamp = 0;
@@ -925,7 +899,8 @@
strerror(-error));
// Don't bother processing this frame if a pause was requested
- if (IsSuspended()) {
+ std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
+ if (post_thread_state_ == PostThreadState::kPauseRequested) {
continue;
}
}
@@ -1055,7 +1030,7 @@
bool HardwareComposer::UpdateLayerConfig(
std::vector<std::shared_ptr<DisplaySurface>>* compositor_surfaces) {
- std::lock_guard<std::mutex> autolock(layer_mutex_);
+ std::lock_guard<std::mutex> layer_lock(layer_mutex_);
if (!display_surfaces_updated_)
return false;
@@ -1526,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/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index cfe8c84..33f090d 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -191,7 +191,6 @@
bool Suspend();
bool Resume();
- bool IsSuspended() const { return pause_post_thread_; }
// Get the HMD display metrics for the current display.
DisplayMetrics GetHmdDisplayMetrics() const;
@@ -227,7 +226,6 @@
private:
int32_t EnableVsync(bool enabled);
- int32_t SetPowerMode(hwc2_display_t display, hwc2_power_mode_t mode);
class ComposerCallback : public Hwc2::IComposerCallback {
public:
@@ -263,7 +261,7 @@
void PostThread();
int ReadWaitPPState();
- int BlockUntilVSync();
+ int BlockUntilVSync(/*out*/ bool* suspend_requested);
int ReadVSyncTimestamp(int64_t* timestamp);
int WaitForVSync(int64_t* timestamp);
int SleepUntil(int64_t wakeup_timestamp);
@@ -303,8 +301,6 @@
void HandlePendingScreenshots();
- void PausePostThread();
-
// Hardware composer HAL device.
std::unique_ptr<Hwc2::Composer> hwc2_hidl_;
sp<ComposerCallback> callbacks_;
@@ -329,9 +325,6 @@
bool display_surfaces_updated_;
bool hardware_layers_need_update_;
- // Cache whether the display was turned on by us
- bool display_on_; // TODO(hendrikw): The display is always on. Revisit.
-
// Layer array for handling buffer flow into hardware composer layers.
// Note that the first array is the actual storage for the layer objects,
// and the latter is an array of pointers, which can be freely re-arranged
@@ -347,16 +340,35 @@
// Handler to hook vsync events outside of this class.
VSyncCallback vsync_callback_;
- // Thread and condition for managing the layer posting thread. This thread
- // wakes up a short time before vsync to hand buffers to post processing and
- // the results to hardware composer.
+ // The layer posting thread. This thread wakes up a short time before vsync to
+ // hand buffers to post processing and the results to hardware composer.
std::thread post_thread_;
+ enum class PostThreadState {
+ // post_thread_state_ starts off paused. When suspending, the control thread
+ // will block until post_thread_state_ == kPaused, indicating the post
+ // thread has completed the transition to paused (most importantly: no more
+ // hardware composer calls).
+ kPaused,
+ // post_thread_state_ is set to kRunning by the control thread (either
+ // surface flinger's main thread or the vr flinger dispatcher thread). The
+ // post thread blocks until post_thread_state_ == kRunning.
+ kRunning,
+ // Set by the control thread to indicate the post thread should pause. The
+ // post thread will change post_thread_state_ from kPauseRequested to
+ // kPaused when it stops.
+ kPauseRequested
+ };
// Control variables to control the state of the post thread
+ PostThreadState post_thread_state_;
+ // Used to wake the post thread up while it's waiting for vsync, for faster
+ // transition to the paused state.
pdx::LocalHandle terminate_post_thread_event_fd_;
- bool pause_post_thread_;
- std::mutex thread_pause_mutex_;
- std::condition_variable thread_pause_semaphore_;
+ // post_thread_state_mutex_ should be held before checking or modifying
+ // post_thread_state_.
+ std::mutex post_thread_state_mutex_;
+ // Used to communicate between the control thread and the post thread.
+ std::condition_variable post_thread_state_cond_var_;
// Backlight LED brightness sysfs node.
pdx::LocalHandle backlight_brightness_fd_;
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 60c4b36..865313c 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -108,8 +108,6 @@
],
static_libs: ["libEGL_getProcAddress"],
ldflags: ["-Wl,--exclude-libs=ALL"],
-
- required: ["egl.cfg"],
}
cc_defaults {
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 21e76f5..2f42ab6 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -1,12 +1 @@
LOCAL_PATH:= $(call my-dir)
-
-# OpenGL drivers config file
-ifneq ($(BOARD_EGL_CFG),)
-include $(CLEAR_VARS)
-LOCAL_MODULE := egl.cfg
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
-LOCAL_SRC_FILES := ../../../../$(BOARD_EGL_CFG)
-include $(BUILD_PREBUILT)
-endif
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 01d7bbb..b1ca13d 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -31,6 +31,7 @@
#include <cutils/properties.h>
#include <log/log.h>
#include <utils/Trace.h>
+#include <ui/GraphicsEnv.h>
#include <EGL/egl.h>
@@ -147,26 +148,11 @@
// ----------------------------------------------------------------------------
Loader::Loader()
- : getProcAddress(NULL),
- mLibGui(nullptr),
- mGetDriverNamespace(nullptr)
+ : getProcAddress(NULL)
{
- // FIXME: See note in GraphicsEnv.h about android_getDriverNamespace().
- // libgui should already be loaded in any process that uses libEGL, but
- // if for some reason it isn't, then we're not going to get a driver
- // namespace anyway, so don't force it to be loaded.
- mLibGui = dlopen("libgui.so", RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
- if (!mLibGui) {
- ALOGD("failed to load libgui: %s", dlerror());
- return;
- }
- mGetDriverNamespace = reinterpret_cast<decltype(mGetDriverNamespace)>(
- dlsym(mLibGui, "android_getDriverNamespace"));
}
Loader::~Loader() {
- if (mLibGui)
- dlclose(mLibGui);
}
static void* load_wrapper(const char* path) {
@@ -483,11 +469,9 @@
ATRACE_CALL();
void* dso = nullptr;
- if (mGetDriverNamespace) {
- android_namespace_t* ns = mGetDriverNamespace();
- if (ns) {
- dso = load_updated_driver(kind, ns);
- }
+ android_namespace_t* ns = android_getDriverNamespace();
+ if (ns) {
+ dso = load_updated_driver(kind, ns);
}
if (!dso) {
dso = load_system_driver(kind);
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index d0435e7..b0743a5 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -25,8 +25,6 @@
#include <utils/Singleton.h>
#include <utils/String8.h>
-#include <gui/GraphicsEnv.h>
-
#include <EGL/egl.h>
// ----------------------------------------------------------------------------
@@ -56,9 +54,6 @@
getProcAddressType getProcAddress;
- void* mLibGui;
- decltype(android_getDriverNamespace)* mGetDriverNamespace;
-
public:
~Loader();
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 1672397..2782ed7 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <string.h>
-#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
#include <system/window.h>
#include <EGL/egl.h>
@@ -1833,7 +1833,8 @@
{
clearError();
- int usage = 0;
+ uint64_t producerUsage = 0;
+ uint64_t consumerUsage = 0;
uint32_t width = 0;
uint32_t height = 0;
uint32_t format = 0;
@@ -1866,13 +1867,13 @@
GET_NONNEGATIVE_VALUE(EGL_LAYER_COUNT_ANDROID, layer_count);
case EGL_NATIVE_BUFFER_USAGE_ANDROID:
if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) {
- usage |= GRALLOC_USAGE_PROTECTED;
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
}
if (value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) {
- usage |= GRALLOC_USAGE_HW_RENDER;
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
}
if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) {
- usage |= GRALLOC_USAGE_HW_TEXTURE;
+ consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
}
break;
default:
@@ -1940,8 +1941,10 @@
CHECK_ERROR_CONDITION("Unable to write format");
err = data.writeUint32(layer_count);
CHECK_ERROR_CONDITION("Unable to write layer count");
- err = data.writeUint32(usage);
- CHECK_ERROR_CONDITION("Unable to write usage");
+ err = data.writeUint64(producerUsage);
+ CHECK_ERROR_CONDITION("Unable to write producer usage");
+ err = data.writeUint64(consumerUsage);
+ CHECK_ERROR_CONDITION("Unable to write consumer usage");
err = data.writeUtf8AsUtf16(
std::string("[eglCreateNativeClientBufferANDROID pid ") +
std::to_string(getpid()) + ']');
@@ -1958,12 +1961,15 @@
err = gBuffer->initCheck();
if (err != NO_ERROR) {
ALOGE("Unable to create native buffer "
- "{ w=%u, h=%u, f=%u, u=%#x, lc=%u}: %#x", width, height, format,
- usage, layer_count, err);
+ "{ w=%u, h=%u, f=%u, pu=%" PRIx64 " cu=%" PRIx64 ", lc=%u} %#x",
+ width, height, format, producerUsage, consumerUsage,
+ layer_count, err);
goto error_condition;
}
- ALOGV("Created new native buffer %p { w=%u, h=%u, f=%u, u=%#x, lc=%u}",
- gBuffer, width, height, format, usage, layer_count);
+ ALOGV("Created new native buffer %p { w=%u, h=%u, f=%u, pu=%" PRIx64
+ " cu=%" PRIx64 ", lc=%u}",
+ gBuffer, width, height, format, producerUsage, consumerUsage,
+ layer_count);
return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
#undef CHECK_ERROR_CONDITION
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index 2b9c38e..1cd40b3 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -20,7 +20,10 @@
#include <EGL/egl.h>
#include <gui/Surface.h>
-
+#include <gui/IConsumerListener.h>
+#include <gui/IProducerListener.h>
+#include <gui/IGraphicBufferConsumer.h>
+#include <gui/BufferQueue.h>
namespace android {
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/Android.mk b/services/surfaceflinger/Android.mk
index 0e05d54..aa8f189 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -49,14 +49,11 @@
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-ifeq ($(TARGET_IN_VR_MODE),true)
- LOCAL_CFLAGS += -DIN_VR_MODE
-endif
-
ifeq ($(TARGET_USES_HWC2),true)
LOCAL_CFLAGS += -DUSE_HWC2
LOCAL_SRC_FILES += \
SurfaceFlinger.cpp \
+ VrStateCallbacks.cpp \
DisplayHardware/HWComposer.cpp
ifeq ($(TARGET_USES_HWC2ON1ADAPTER), true)
LOCAL_CFLAGS += -DBYPASS_IHWC
@@ -134,7 +131,13 @@
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
-LOCAL_STATIC_LIBRARIES := libhwcomposer-command-buffer libtrace_proto libvkjson
+LOCAL_STATIC_LIBRARIES := \
+ libhwcomposer-command-buffer \
+ libtrace_proto \
+ libvkjson \
+ libvr_manager \
+ libvrflinger
+
LOCAL_SHARED_LIBRARIES := \
android.dvr.composer@1.0 \
android.hardware.graphics.allocator@2.0 \
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 1bd9616..3e9ef24 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"
@@ -123,13 +124,11 @@
endCommand();
}
-Composer::Composer() : mWriter(kWriterInitialSize)
+Composer::Composer(bool useVrComposer)
+ : mWriter(kWriterInitialSize),
+ mIsUsingVrComposer(useVrComposer)
{
-#if defined(IN_VR_MODE)
- mIsInVrMode = true;
-#endif
-
- if (mIsInVrMode) {
+ if (mIsUsingVrComposer) {
mComposer = IComposer::getService("vr_hwcomposer");
} else {
mComposer = IComposer::getService("hwcomposer");
@@ -221,9 +220,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 +425,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 +471,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 +502,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;
}
@@ -621,8 +620,7 @@
Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
uint32_t appId)
{
- if (mIsInVrMode)
- {
+ if (mIsUsingVrComposer) {
mWriter.selectDisplay(display);
mWriter.selectLayer(layer);
mWriter.setLayerInfo(type, appId);
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 329d787..18af9dd 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -26,7 +26,6 @@
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <utils/StrongPointer.h>
#include <IComposerCommandBuffer.h>
-#include <MessageQueue.h>
namespace android {
@@ -128,7 +127,7 @@
// Composer is a wrapper to IComposer, a proxy to server-side composer.
class Composer {
public:
- Composer();
+ Composer(bool useVrComposer);
std::vector<IComposer::Capability> getCapabilities();
std::string dumpDebugInfo();
@@ -136,6 +135,7 @@
void registerCallback(const sp<IComposerCallback>& callback);
uint32_t getMaxVirtualDisplayCount();
+ bool isUsingVrComposer() const { return mIsUsingVrComposer; }
Error createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display* outDisplay);
Error destroyVirtualDisplay(Display display);
@@ -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);
@@ -240,7 +248,9 @@
CommandWriter mWriter;
CommandReader mReader;
- bool mIsInVrMode = false;
+ // When true, the we attach to the vr_hwcomposer service instead of the
+ // hwcomposer. This allows us to redirect surfaces to 3d surfaces in vr.
+ const bool mIsUsingVrComposer;
};
} // namespace Hwc2
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..a25e8a1 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -135,8 +135,8 @@
mSetLayerVisibleRegion(nullptr),
mSetLayerZOrder(nullptr),
#else
-Device::Device()
- : mComposer(std::make_unique<Hwc2::Composer>()),
+Device::Device(bool useVrComposer)
+ : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
#endif // BYPASS_IHWC
mCapabilities(),
mDisplays(),
@@ -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..93eb999 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -67,7 +67,10 @@
#ifdef BYPASS_IHWC
explicit Device(hwc2_device_t* device);
#else
- Device();
+ // useVrComposer is passed to the composer HAL. When true, the composer HAL
+ // will use the vr composer service, otherwise it uses the real hardware
+ // composer.
+ Device(bool useVrComposer);
#endif
~Device();
@@ -106,6 +109,12 @@
bool hasCapability(HWC2::Capability capability) const;
+#ifdef BYPASS_IHWC
+ android::Hwc2::Composer* getComposer() { return nullptr; }
+#else
+ android::Hwc2::Composer* getComposer() { return mComposer.get(); }
+#endif
+
private:
// Initialization methods
@@ -322,7 +331,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 +393,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..1c99036 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -49,6 +49,7 @@
#include "HWComposer.h"
#include "HWC2On1Adapter.h"
#include "HWC2.h"
+#include "ComposerHal.h"
#include "../Layer.h" // needed only for debugging
#include "../SurfaceFlinger.h"
@@ -59,7 +60,7 @@
// ---------------------------------------------------------------------------
-HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
+HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger, bool useVrComposer)
: mFlinger(flinger),
mAdapter(),
mHwcDevice(),
@@ -76,7 +77,7 @@
mVSyncCounts[i] = 0;
}
- loadHwcModule();
+ loadHwcModule(useVrComposer);
}
HWComposer::~HWComposer() {}
@@ -105,11 +106,13 @@
}
// Load and prepare the hardware composer module. Sets mHwc.
-void HWComposer::loadHwcModule()
+void HWComposer::loadHwcModule(bool useVrComposer)
{
ALOGV("loadHwcModule");
#ifdef BYPASS_IHWC
+ (void)useVrComposer; // Silence unused parameter warning.
+
hw_module_t const* module;
if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
@@ -142,7 +145,7 @@
static_cast<hwc2_device_t*>(mAdapter.get()));
}
#else
- mHwcDevice = std::make_unique<HWC2::Device>();
+ mHwcDevice = std::make_unique<HWC2::Device>(useVrComposer);
#endif
mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
@@ -444,7 +447,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 +460,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));
@@ -866,6 +870,14 @@
}
*/
+bool HWComposer::isUsingVrComposer() const {
+#ifdef BYPASS_IHWC
+ return false;
+#else
+ return getComposer()->isUsingVrComposer();
+#endif
+}
+
void HWComposer::dump(String8& result) const {
// TODO: In order to provide a dump equivalent to HWC1, we need to shadow
// all the state going into the layers. This is probably better done in
@@ -894,5 +906,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..7b61e0e 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>
@@ -75,7 +77,10 @@
virtual ~EventHandler() {}
};
- HWComposer(const sp<SurfaceFlinger>& flinger);
+ // useVrComposer is passed to the composer HAL. When true, the composer HAL
+ // will use the vr composer service, otherwise it uses the real hardware
+ // composer.
+ HWComposer(const sp<SurfaceFlinger>& flinger, bool useVrComposer);
~HWComposer();
@@ -94,7 +99,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.
@@ -162,13 +168,16 @@
status_t setActiveColorMode(int32_t displayId, android_color_mode_t mode);
+ bool isUsingVrComposer() const;
+
// for debugging ----------------------------------------------------------
void dump(String8& out) const;
+ android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
private:
static const int32_t VIRTUAL_DISPLAY_ID_BASE = 2;
- void loadHwcModule();
+ void loadHwcModule(bool useVrComposer);
bool isValidDisplay(int32_t displayId) const;
static void validateChange(HWC2::Composition from, HWC2::Composition to);
@@ -224,6 +233,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..12166a8 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,11 +405,18 @@
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);
}
}
+ void clearHwcLayers() {
+ mHwcLayers.clear();
+ }
+
#endif
// -----------------------------------------------------------------------
@@ -489,6 +503,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 +657,7 @@
FenceTimeline mReleaseTimeline;
// main thread
+ int mActiveBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
sp<GraphicBuffer> mActiveBuffer;
sp<NativeHandle> mSidebandStream;
Rect mCurrentCrop;
@@ -681,6 +697,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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 55ad5fc..30bce55 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -36,6 +36,8 @@
#include <binder/MemoryHeapBase.h>
#include <binder/PermissionCache.h>
+#include <dvr/vr_flinger.h>
+
#include <ui/DisplayInfo.h>
#include <ui/DisplayStatInfo.h>
@@ -73,6 +75,7 @@
#include "LayerDim.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
+#include "VrStateCallbacks.h"
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
@@ -155,7 +158,10 @@
mLayersRemoved(false),
mLayersAdded(false),
mRepaintEverything(0),
- mRenderEngine(NULL),
+ mHwc(nullptr),
+ mRealHwc(nullptr),
+ mVrHwc(nullptr),
+ mRenderEngine(nullptr),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
@@ -180,7 +186,8 @@
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0),
- mNumLayers(0)
+ mNumLayers(0),
+ mEnterVrMode(false)
{
ALOGI("SurfaceFlinger is starting");
@@ -208,9 +215,9 @@
mPropagateBackpressure = !atoi(value);
ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
- property_get("debug.sf.disable_hwc_vds", value, "0");
- mUseHwcVirtualDisplays = !atoi(value);
- ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
+ property_get("debug.sf.enable_hwc_vds", value, "0");
+ mUseHwcVirtualDisplays = atoi(value);
+ ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
property_get("ro.sf.disable_triple_buffer", value, "1");
mLayerTripleBufferingDisabled = atoi(value);
@@ -227,6 +234,14 @@
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglTerminate(display);
+
+ if (mVrStateCallbacks.get()) {
+ sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
+ defaultServiceManager()->checkService(String16("vrmanager")));
+ if (vrManagerService.get()) {
+ vrManagerService->unregisterListener(mVrStateCallbacks);
+ }
+ }
}
void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
@@ -361,6 +376,13 @@
const int LOGTAG_SF_STOP_BOOTANIM = 60110;
LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
+
+ sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
+ defaultServiceManager()->checkService(String16("vrmanager")));
+ if (vrManagerService.get()) {
+ mVrStateCallbacks = new VrStateCallbacks(*this);
+ vrManagerService->registerListener(mVrStateCallbacks);
+ }
}
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
@@ -556,7 +578,9 @@
// Drop the state lock while we initialize the hardware composer. We drop
// the lock because on creation, it will call back into SurfaceFlinger to
// initialize the primary display.
- mHwc = new HWComposer(this);
+ LOG_ALWAYS_FATAL_IF(mEnterVrMode, "Starting in vr mode is not currently supported.");
+ mRealHwc = new HWComposer(this, false);
+ mHwc = mRealHwc;
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
Mutex::Autolock _l(mStateLock);
@@ -1104,7 +1128,13 @@
bool isSecure = true;
int32_t type = DisplayDevice::DISPLAY_PRIMARY;
- createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+
+ // When we're using the vr composer, the assumption is that we've
+ // already created the IBinder object for the primary display.
+ if (!mHwc->isUsingVrComposer()) {
+ createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+ }
+
wp<IBinder> token = mBuiltinDisplays[type];
sp<IGraphicBufferProducer> producer;
@@ -1139,10 +1169,79 @@
enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
}
+void SurfaceFlinger::clearHwcLayers(const LayerVector& layers) {
+ for (size_t i = 0; i < layers.size(); ++i) {
+ layers[i]->clearHwcLayers();
+ }
+}
+
+void SurfaceFlinger::resetHwc() {
+ disableHardwareVsync(true);
+ clearHwcLayers(mDrawingState.layersSortedByZ);
+ clearHwcLayers(mCurrentState.layersSortedByZ);
+ // Clear the drawing state so that the logic inside of
+ // handleTransactionLocked will fire. It will determine the delta between
+ // mCurrentState and mDrawingState and re-apply all changes when we make the
+ // transition.
+ mDrawingState.displays.clear();
+ mDisplays.clear();
+}
+
+void SurfaceFlinger::updateVrMode() {
+ {
+ Mutex::Autolock _l(mStateLock);
+ bool enteringVrMode = mEnterVrMode;
+ if (enteringVrMode == mHwc->isUsingVrComposer()) {
+ return;
+ }
+
+ if (enteringVrMode) {
+ // Start vrflinger thread, if it hasn't been started already.
+ if (!mVrFlinger) {
+ mVrFlinger = std::make_unique<dvr::VrFlinger>();
+ int err = mVrFlinger->Run(mHwc->getComposer());
+ if (err != NO_ERROR) {
+ ALOGE("Failed to run vrflinger: %s (%d)", strerror(-err), err);
+ mVrFlinger.reset();
+ mEnterVrMode = false;
+ return;
+ }
+ }
+
+ if (!mVrHwc) {
+ mVrHwc = new HWComposer(this, true);
+ ALOGV("Vr HWC created");
+ }
+
+ resetHwc();
+
+ mHwc = mVrHwc;
+ mVrFlinger->EnterVrMode();
+ } else {
+ mVrFlinger->ExitVrMode();
+
+ resetHwc();
+
+ mHwc = mRealHwc;
+ enableHardwareVsync();
+ }
+
+ mVisibleRegionsDirty = true;
+ invalidateHwcGeometry();
+ android_atomic_or(1, &mRepaintEverything);
+ setTransactionFlags(eDisplayTransactionNeeded);
+ }
+ if (mVrHwc) {
+ mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
+ }
+}
+
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
+ updateVrMode();
+
bool frameMissed = !mHadClientComposition &&
mPreviousPresentFence != Fence::NO_FENCE &&
mPreviousPresentFence->getSignalTime() == INT64_MAX;
@@ -1763,16 +1862,10 @@
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
- if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
- hwcId = DisplayDevice::DISPLAY_EXTERNAL;
- dispSurface = new FramebufferSurface(*mHwc,
- DisplayDevice::DISPLAY_EXTERNAL,
- bqConsumer);
- producer = bqProducer;
- } else {
- ALOGE("Attempted to add non-external non-virtual"
- " display");
- }
+
+ hwcId = state.type;
+ dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
+ producer = bqProducer;
}
const wp<IBinder>& display(curr.keyAt(i));
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 55735b1..6dfdf08 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_SURFACE_FLINGER_H
#define ANDROID_SURFACE_FLINGER_H
+#include <memory>
#include <stdint.h>
#include <sys/types.h>
@@ -81,6 +82,11 @@
class EventControlThread;
class VSyncSource;
class InjectVSyncSource;
+class VrStateCallbacks;
+
+namespace dvr {
+class VrFlinger;
+} // namespace dvr
// ---------------------------------------------------------------------------
@@ -156,6 +162,7 @@
friend class EventThread;
friend class Layer;
friend class MonitoredProducer;
+ friend class VrStateCallbacks;
// This value is specified in number of frames. Log frame stats at most
// every half hour.
@@ -460,6 +467,19 @@
bool isLayerTripleBufferingDisabled() const {
return this->mLayerTripleBufferingDisabled;
}
+
+#ifdef USE_HWC2
+ /* ------------------------------------------------------------------------
+ * VrFlinger
+ */
+ void clearHwcLayers(const LayerVector& layers);
+ void resetHwc();
+
+ // Check to see if we should change to or from vr mode, and if so, perform
+ // the handoff.
+ void updateVrMode();
+#endif
+
/* ------------------------------------------------------------------------
* Attributes
*/
@@ -481,8 +501,13 @@
// access must be protected by mInvalidateLock
volatile int32_t mRepaintEverything;
- // constant members (no synchronization needed for access)
+ // current, real and vr hardware composers.
HWComposer* mHwc;
+#ifdef USE_HWC2
+ HWComposer* mRealHwc;
+ HWComposer* mVrHwc;
+#endif
+ // constant members (no synchronization needed for access)
RenderEngine* mRenderEngine;
nsecs_t mBootTime;
bool mGpuToCpuSupported;
@@ -495,6 +520,10 @@
EGLDisplay mEGLDisplay;
sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];
+#ifdef USE_HWC2
+ std::unique_ptr<dvr::VrFlinger> mVrFlinger;
+#endif
+
// Can only accessed from the main thread, these members
// don't need synchronization
State mDrawingState;
@@ -532,7 +561,7 @@
bool mPropagateBackpressure = true;
#endif
SurfaceInterceptor mInterceptor;
- bool mUseHwcVirtualDisplays = true;
+ bool mUseHwcVirtualDisplays = false;
// Restrict layers to use two buffers in their bufferqueues.
bool mLayerTripleBufferingDisabled = false;
@@ -601,6 +630,12 @@
// Verify that transaction is being called by an approved process:
// either AID_GRAPHICS or AID_SYSTEM.
status_t CheckTransactCodeCredentials(uint32_t code);
+
+#ifdef USE_HWC2
+ sp<VrStateCallbacks> mVrStateCallbacks;
+
+ std::atomic<bool> mEnterVrMode;
+#endif
};
}; // namespace android
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/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 240844d..7e6eb03 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -188,9 +188,9 @@
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
- property_get("debug.sf.disable_hwc_vds", value, "0");
- mUseHwcVirtualDisplays = !atoi(value);
- ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
+ property_get("debug.sf.enable_hwc_vds", value, "0");
+ mUseHwcVirtualDisplays = atoi(value);
+ ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
property_get("ro.sf.disable_triple_buffer", value, "1");
mLayerTripleBufferingDisabled = atoi(value);
diff --git a/services/surfaceflinger/VrStateCallbacks.cpp b/services/surfaceflinger/VrStateCallbacks.cpp
new file mode 100644
index 0000000..a924def
--- /dev/null
+++ b/services/surfaceflinger/VrStateCallbacks.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VrStateCallbacks.h"
+#include "SurfaceFlinger.h"
+
+namespace android {
+
+VrStateCallbacks::VrStateCallbacks(SurfaceFlinger& flinger)
+ : mFlinger(flinger) {}
+
+void VrStateCallbacks::onVrStateChanged(bool enabled) {
+ mFlinger.mEnterVrMode = enabled;
+ mFlinger.signalTransaction();
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/VrStateCallbacks.h b/services/surfaceflinger/VrStateCallbacks.h
new file mode 100644
index 0000000..4e655d3
--- /dev/null
+++ b/services/surfaceflinger/VrStateCallbacks.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VR_STATE_CALLBACKS_H
+#define ANDROID_VR_STATE_CALLBACKS_H
+
+#include <vr/vr_manager/vr_manager.h>
+
+namespace android {
+
+class SurfaceFlinger;
+
+class VrStateCallbacks : public BnVrStateCallbacks {
+public:
+ VrStateCallbacks(SurfaceFlinger& flinger);
+ void onVrStateChanged(bool enabled) override;
+
+private:
+ SurfaceFlinger& mFlinger;
+};
+
+} // namespace android
+
+#endif // ANDROID_VR_STATE_CALLBACKS_H
diff --git a/services/vr/vr_window_manager/Android.mk_disable b/services/vr/vr_window_manager/Android.mk
similarity index 77%
rename from services/vr/vr_window_manager/Android.mk_disable
rename to services/vr/vr_window_manager/Android.mk
index 9a6f752..47d9dcc 100644
--- a/services/vr/vr_window_manager/Android.mk_disable
+++ b/services/vr/vr_window_manager/Android.mk
@@ -14,6 +14,30 @@
LOCAL_PATH := $(call my-dir)
+binder_src := \
+ vr_window_manager_binder.cpp \
+ aidl/android/service/vr/IVrWindowManager.aidl
+
+static_libs := \
+ libcutils
+
+shared_libs := \
+ libbase \
+ libbinder \
+ libutils
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(binder_src)
+LOCAL_STATIC_LIBRARIES := $(static_libs)
+LOCAL_SHARED_LIBRARIES := $(shared_libs)
+LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CFLAGS += -DLOG_TAG=\"VrWindowManager\"
+LOCAL_LDLIBS := -llog
+LOCAL_MODULE := libvrwm_binder
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_STATIC_LIBRARY)
+
+
native_src := \
application.cpp \
controller_mesh.cpp \
@@ -76,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
@@ -93,8 +116,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(native_src)
-LOCAL_C_INCLUDES := hardware/qcom/display/msm8996/libgralloc
-LOCAL_STATIC_LIBRARIES := $(static_libs)
+LOCAL_STATIC_LIBRARIES := $(static_libs) libvrwm_binder
LOCAL_SHARED_LIBRARIES := $(shared_libs)
LOCAL_SHARED_LIBRARIES += libgvr
LOCAL_STATIC_LIBRARIES += libgvr_ext
@@ -126,3 +148,27 @@
LOCAL_AAPT_FLAGS += --extra-packages com.google.vr.cardboard
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
+
+
+cmd_src := \
+ vr_wm_ctl.cpp \
+ aidl/android/service/vr/IVrWindowManager.aidl
+
+static_libs := \
+ libcutils
+
+shared_libs := \
+ libbase \
+ libbinder \
+ libutils
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(cmd_src)
+LOCAL_STATIC_LIBRARIES := $(static_libs)
+LOCAL_SHARED_LIBRARIES := $(shared_libs)
+LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CFLAGS += -DLOG_TAG=\"vrwmctl\"
+LOCAL_LDLIBS := -llog
+LOCAL_MODULE := vr_wm_ctl
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_EXECUTABLE)
diff --git a/services/vr/vr_window_manager/AndroidManifest.xml b/services/vr/vr_window_manager/AndroidManifest.xml
index 5cc4b5c..d5008a3 100644
--- a/services/vr/vr_window_manager/AndroidManifest.xml
+++ b/services/vr/vr_window_manager/AndroidManifest.xml
@@ -27,7 +27,7 @@
<service android:name=".VrWindowManagerService" />
<receiver android:name="com.google.vr.windowmanager.BootCompletedReceiver">
<intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <!-- action android:name="android.intent.action.BOOT_COMPLETED" / -->
</intent-filter>
</receiver>
</application>
diff --git a/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl b/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl
new file mode 100644
index 0000000..b5dbb8b
--- /dev/null
+++ b/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.vr;
+
+/** @hide */
+interface IVrWindowManager {
+ const String SERVICE_NAME = "vr_window_manager";
+ void connectController(in FileDescriptor fd) = 0;
+ void disconnectController() = 1;
+ void enterVrMode() = 2;
+ void exitVrMode() = 3;
+ void setDebugMode(int mode) = 4;
+}
+
diff --git a/services/vr/vr_window_manager/application.cpp b/services/vr/vr_window_manager/application.cpp
index 62db639..895f25f 100644
--- a/services/vr/vr_window_manager/application.cpp
+++ b/services/vr/vr_window_manager/application.cpp
@@ -226,10 +226,8 @@
if (fade_value_ > 1.0f)
fade_value_ = 1.0f;
- quat controller_quat(controller_orientation_.qw, controller_orientation_.qx,
- controller_orientation_.qy, controller_orientation_.qz);
- controller_position_ = elbow_model_.Update(
- delta, last_pose_.GetRotation(), controller_quat, false);
+ controller_position_ = elbow_model_.Update(delta, last_pose_.GetRotation(),
+ controller_orientation_, false);
dvrBeginRenderFrameEds(graphics_context_, pose.orientation,
pose.translation);
@@ -257,6 +255,61 @@
}
void Application::ProcessControllerInput() {
+ if (controller_data_provider_) {
+ shmem_controller_active_ = false;
+ const void* data = controller_data_provider_->LockControllerData();
+ // TODO(kpschoedel): define wire format.
+ if (data) {
+ struct wire_format {
+ uint32_t version;
+ uint32_t timestamph;
+ uint32_t timestampl;
+ uint32_t quat_count;
+ float q[4];
+ uint32_t buttonsh;
+ uint32_t buttonsl;
+ } __attribute__((__aligned__(32)));
+ const wire_format* wire_data = static_cast<const wire_format*>(data);
+ static uint64_t last_timestamp = 0;
+ if (wire_data->version == 1) {
+ shmem_controller_active_ = true;
+ uint64_t timestamp =
+ (((uint64_t)wire_data->timestamph) << 32) | wire_data->timestampl;
+ if (timestamp == last_timestamp) {
+ static uint64_t last_logged_timestamp = 0;
+ if (last_logged_timestamp != last_timestamp) {
+ last_logged_timestamp = last_timestamp;
+ ALOGI("Controller shmem stale T=0x%" PRIX64, last_timestamp);
+ }
+ } else {
+ last_timestamp = timestamp;
+ controller_orientation_ = quat(wire_data->q[3], wire_data->q[0],
+ wire_data->q[1], wire_data->q[2]);
+ shmem_controller_buttons_ =
+ (((uint64_t)wire_data->buttonsh) << 32) | wire_data->buttonsl;
+ }
+ } else if (wire_data->version == 0xFEEDFACE) {
+ static bool logged_init = false;
+ if (!logged_init) {
+ logged_init = true;
+ ALOGI("Controller shmem waiting for data");
+ }
+ }
+ }
+ controller_data_provider_->UnlockControllerData();
+ if (shmem_controller_active_) {
+ // TODO(kpschoedel): change to ALOGV or remove.
+ ALOGI("Controller shmem orientation: %f %f %f %f",
+ controller_orientation_.x(), controller_orientation_.y(),
+ controller_orientation_.z(), controller_orientation_.w());
+ if (shmem_controller_buttons_) {
+ ALOGI("Controller shmem buttons: %017" PRIX64,
+ shmem_controller_buttons_);
+ }
+ return;
+ }
+ }
+
if (!controller_)
return;
@@ -289,8 +342,11 @@
controller_connection_state_logged_ = false;
}
- if (new_api_status == gvr::kControllerApiOk)
- controller_orientation_ = controller_state_->GetOrientation();
+ if (new_api_status == gvr::kControllerApiOk) {
+ gvr_quatf orientation = controller_state_->GetOrientation();
+ controller_orientation_ =
+ quat(orientation.qw, orientation.qx, orientation.qy, orientation.qz);
+ }
controller_api_status_ = new_api_status;
controller_connection_state_ = new_connection_state;
diff --git a/services/vr/vr_window_manager/application.h b/services/vr/vr_window_manager/application.h
index 47a0927..0c6385f 100644
--- a/services/vr/vr_window_manager/application.h
+++ b/services/vr/vr_window_manager/application.h
@@ -11,6 +11,7 @@
#include <chrono>
#include <mutex>
+#include "controller_data_provider.h"
#include "elbow_model.h"
struct DvrGraphicsContext;
@@ -32,6 +33,10 @@
void DrawFrame();
+ void SetControllerDataProvider(ControllerDataProvider* provider) {
+ controller_data_provider_ = provider;
+ }
+
protected:
enum class MainThreadTask {
EnteringVrMode,
@@ -69,9 +74,11 @@
std::unique_ptr<gvr::ControllerState> controller_state_;
gvr::ControllerApiStatus controller_api_status_;
gvr::ControllerConnectionState controller_connection_state_;
- gvr_quatf controller_orientation_;
+ quat controller_orientation_;
+ bool shmem_controller_active_ = false;
bool controller_api_status_logged_;
bool controller_connection_state_logged_;
+ uint64_t shmem_controller_buttons_;
bool is_visible_ = false;
std::chrono::time_point<std::chrono::system_clock> visibility_button_press_;
@@ -93,6 +100,9 @@
jobject app_context_;
jobject class_loader_;
+ // Controller data provider from shared memory buffer.
+ ControllerDataProvider* controller_data_provider_ = nullptr;
+
Application(const Application&) = delete;
void operator=(const Application&) = delete;
};
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/controller_data_provider.h b/services/vr/vr_window_manager/controller_data_provider.h
new file mode 100644
index 0000000..bc1450c
--- /dev/null
+++ b/services/vr/vr_window_manager/controller_data_provider.h
@@ -0,0 +1,19 @@
+#ifndef VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
+#define VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
+
+namespace android {
+namespace dvr {
+
+class ControllerDataProvider {
+ public:
+ virtual ~ControllerDataProvider() {}
+ // Returns data pointer or nullptr. If pointer is valid, call to
+ // UnlockControllerData is required.
+ virtual const void* LockControllerData() = 0;
+ virtual void UnlockControllerData() = 0;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
\ No newline at end of file
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;
}
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index 11680af..29ade64 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -190,14 +190,6 @@
return layer_transform;
}
-vec3 FromGvrVec3f(const gvr_vec3f& vec3f) {
- return vec3(vec3f.x, vec3f.y, vec3f.z);
-}
-
-quat FromGvrQuatf(const gvr_quatf& quaternion) {
- return quat(quaternion.qw, quaternion.qx, quaternion.qy, quaternion.qz);
-}
-
// Determine if ths frame should be shown or hidden.
ViewMode CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
uint32_t vr_app) {
@@ -302,15 +294,24 @@
}
void ShellView::EnableDebug(bool debug) {
+ ALOGI("EnableDebug(%d)", (int)debug); // XXX TODO delete
QueueTask(debug ? MainThreadTask::EnableDebugMode
: MainThreadTask::DisableDebugMode);
}
void ShellView::VrMode(bool mode) {
+ ALOGI("VrMode(%d)", (int)mode); // XXX TODO delete
QueueTask(mode ? MainThreadTask::EnteringVrMode
: MainThreadTask::ExitingVrMode);
}
+void ShellView::dumpInternal(String8& result) {
+ result.append("[shell]\n");
+ result.appendFormat("initialized = %s\n", initialized_ ? "true" : "false");
+ result.appendFormat("is_visible = %s\n", is_visible_ ? "true" : "false");
+ result.appendFormat("debug_mode = %s\n\n", debug_mode_ ? "true" : "false");
+}
+
void ShellView::AdvanceFrame() {
if (!pending_frames_.empty()) {
// Check if we should advance the frame.
@@ -398,7 +399,11 @@
if (visibility == ViewMode::Hidden && debug_mode_)
visibility = ViewMode::VR;
- current_vr_app_ = frame->layers().front().appid;
+
+ if (frame->layers().empty())
+ current_vr_app_ = 0;
+ else
+ current_vr_app_ = frame->layers().front().appid;
std::unique_lock<std::mutex> l(pending_frame_mutex_);
@@ -418,7 +423,8 @@
// If we are showing ourselves the main thread is not processing anything,
// so give it a kick.
- if (visibility != ViewMode::Hidden && current_frame_.visibility == ViewMode::Hidden) {
+ if (visibility != ViewMode::Hidden &&
+ current_frame_.visibility == ViewMode::Hidden) {
QueueTask(MainThreadTask::EnteringVrMode);
QueueTask(MainThreadTask::Show);
}
@@ -598,23 +604,50 @@
vec3 pointer_location = last_pose_.GetPosition();
quat view_quaternion = last_pose_.GetRotation();
- if (controller_ && controller_api_status_ == gvr::kControllerApiOk) {
- view_quaternion = FromGvrQuatf(controller_orientation_);
+ bool gvr_api_active =
+ controller_ && controller_api_status_ == gvr::kControllerApiOk;
+
+ if (gvr_api_active || shmem_controller_active_) {
+ view_quaternion = controller_orientation_;
vec4 controller_location = controller_translate_ * vec4(0, 0, 0, 1);
pointer_location = vec3(controller_location.x(), controller_location.y(),
controller_location.z());
- if (controller_state_->GetButtonDown(gvr::kControllerButtonClick))
- OnClick(true);
+ if (shmem_controller_active_) {
+ uint64_t buttons = shmem_controller_buttons_;
+ shmem_controller_buttons_ = 0;
+ while (buttons) {
+ switch (buttons & 0xF) {
+ case 0x1:
+ OnClick(false);
+ break;
+ case 0x3:
+ OnTouchpadButton(false, AMOTION_EVENT_BUTTON_BACK);
+ break;
+ case 0x9:
+ OnClick(true);
+ break;
+ case 0xB:
+ OnTouchpadButton(true, AMOTION_EVENT_BUTTON_BACK);
+ break;
+ default:
+ break;
+ }
+ buttons >>= 4;
+ }
+ } else if (controller_) {
+ if (controller_state_->GetButtonDown(gvr::kControllerButtonClick))
+ OnClick(true);
- if (controller_state_->GetButtonUp(gvr::kControllerButtonClick))
- OnClick(false);
+ if (controller_state_->GetButtonUp(gvr::kControllerButtonClick))
+ OnClick(false);
- if (controller_state_->GetButtonDown(gvr::kControllerButtonApp))
- OnTouchpadButton(true, AMOTION_EVENT_BUTTON_BACK);
+ if (controller_state_->GetButtonDown(gvr::kControllerButtonApp))
+ OnTouchpadButton(true, AMOTION_EVENT_BUTTON_BACK);
- if (controller_state_->GetButtonUp(gvr::kControllerButtonApp))
- OnTouchpadButton(false, AMOTION_EVENT_BUTTON_BACK);
+ if (controller_state_->GetButtonUp(gvr::kControllerButtonApp))
+ OnTouchpadButton(false, AMOTION_EVENT_BUTTON_BACK);
+ }
}
vec3 view_direction = vec3(view_quaternion * vec3(0, 0, -1));
@@ -643,7 +676,7 @@
void ShellView::DrawController(const mat4& perspective, const mat4& eye_matrix,
const mat4& head_matrix) {
- if (!controller_)
+ if (!controller_ && !shmem_controller_active_)
return;
controller_program_->Use();
@@ -653,7 +686,7 @@
controller_program_->GetProgram(), "uViewProjection");
glUniformMatrix4fv(view_projection_location, 1, 0, mvp.data());
- quat view_quaternion = FromGvrQuatf(controller_orientation_);
+ quat view_quaternion = controller_orientation_;
view_quaternion.toRotationMatrix();
vec3 world_pos = last_pose_.GetPosition() + controller_position_;
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index ba46e6d..14ad0f3 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -9,6 +9,7 @@
#include "application.h"
#include "reticle.h"
+#include "shell_view_binder_interface.h"
#include "surface_flinger_view.h"
namespace android {
@@ -20,7 +21,9 @@
App,
};
-class ShellView : public Application, public HwcCallback::Client {
+class ShellView : public Application,
+ public android::dvr::ShellViewBinderInterface,
+ public HwcCallback::Client {
public:
ShellView();
virtual ~ShellView();
@@ -31,8 +34,10 @@
int AllocateResources() override;
void DeallocateResources() override;
- void EnableDebug(bool debug);
- void VrMode(bool mode);
+ // ShellViewBinderInterface:
+ void EnableDebug(bool debug) override;
+ void VrMode(bool mode) override;
+ void dumpInternal(String8& result) override;
protected:
void DrawEye(EyeType eye, const mat4& perspective, const mat4& eye_matrix,
diff --git a/services/vr/vr_window_manager/shell_view_binder_interface.h b/services/vr/vr_window_manager/shell_view_binder_interface.h
new file mode 100644
index 0000000..b58e4bd
--- /dev/null
+++ b/services/vr/vr_window_manager/shell_view_binder_interface.h
@@ -0,0 +1,20 @@
+#ifndef VR_WINDOW_MANAGER_SHELL_VIEWBINDER_INTERFACE_H_
+#define VR_WINDOW_MANAGER_SHELL_VIEWBINDER_INTERFACE_H_
+
+namespace android {
+namespace dvr {
+
+class ShellViewBinderInterface {
+ public:
+ ShellViewBinderInterface() {};
+ virtual ~ShellViewBinderInterface() {};
+
+ virtual void EnableDebug(bool debug) = 0;
+ virtual void VrMode(bool mode) = 0;
+ virtual void dumpInternal(String8& result) = 0;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // VR_WINDOW_MANAGER_SHELL_VIEWBINDER_INTERFACE_H_
diff --git a/services/vr/vr_window_manager/vr_window_manager.cpp b/services/vr/vr_window_manager/vr_window_manager.cpp
index 8d9ad79..c51ddee 100644
--- a/services/vr/vr_window_manager/vr_window_manager.cpp
+++ b/services/vr/vr_window_manager/vr_window_manager.cpp
@@ -1,18 +1,33 @@
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include "shell_view.h"
+#include "vr_window_manager_binder.h"
int main(int /* argc */, char** /* argv */) {
+ android::dvr::ShellView app;
+ const int app_status = app.Initialize(nullptr, nullptr, nullptr);
+ LOG_ALWAYS_FATAL_IF(app_status != 0, "failed to initialize: %d", app_status);
+
+ android::service::vr::VrWindowManagerBinder service(app);
+ const int status = service.Initialize();
+ LOG_ALWAYS_FATAL_IF(status != 0, "initialization failed: %d", status);
+
android::ProcessState::self()->startThreadPool();
- android::dvr::ShellView app;
- if (app.Initialize(nullptr, nullptr, nullptr)) {
- ALOGE("Failed to initialize");
- return 1;
- }
+ android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+ const android::status_t service_status = sm->addService(
+ android::service::vr::VrWindowManagerBinder::SERVICE_NAME(), &service,
+ false /*allowIsolated*/);
+ LOG_ALWAYS_FATAL_IF(service_status != android::OK, "service not added: %d",
+ static_cast<int>(service_status));
+
+ app.SetControllerDataProvider(&service);
while (true)
app.DrawFrame();
+ android::IPCThreadState::self()->joinThreadPool();
return 0;
}
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder.cpp b/services/vr/vr_window_manager/vr_window_manager_binder.cpp
new file mode 100644
index 0000000..c2138b7
--- /dev/null
+++ b/services/vr/vr_window_manager/vr_window_manager_binder.cpp
@@ -0,0 +1,156 @@
+#include "vr_window_manager_binder.h"
+
+#include <inttypes.h>
+#include <sys/mman.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
+#include <binder/Status.h>
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+#include <utils/Errors.h>
+
+namespace android {
+namespace service {
+namespace vr {
+
+namespace {
+const String16 kDumpPermission("android.permission.DUMP");
+const String16 kSendMeControllerInputPermission("TODO"); // TODO(kpschoedel)
+} // anonymous namespace
+
+constexpr size_t AshmemControllerDataProvider::kRegionLength;
+
+status_t AshmemControllerDataProvider::Connect(const int in_fd) {
+ if (in_fd < 0) {
+ return BAD_VALUE;
+ }
+ if (fd_.get() >= 0) {
+ // The VrCore is dead. Long live the VrCore.
+ Disconnect();
+ }
+ void* const shared_region =
+ ::mmap(nullptr, kRegionLength, PROT_READ, MAP_SHARED, in_fd, 0);
+ if (shared_region == MAP_FAILED) {
+ shared_region_ = nullptr;
+ return NO_MEMORY;
+ }
+
+ errno = 0;
+ const int fd = ::fcntl(in_fd, F_DUPFD_CLOEXEC, 0);
+ if (fd < 0) {
+ ::munmap(shared_region, kRegionLength);
+ return -errno;
+ }
+ fd_.reset(fd);
+ ALOGI("controller connected %d -> %d @ %p", in_fd, fd, shared_region);
+
+ std::lock_guard<std::mutex> guard(mutex_);
+ shared_region_ = shared_region;
+ return OK;
+}
+
+status_t AshmemControllerDataProvider::Disconnect() {
+ if (shared_region_ == nullptr || fd_.get() < 0) {
+ return INVALID_OPERATION;
+ }
+ std::lock_guard<std::mutex> guard(mutex_);
+ ::munmap(shared_region_, kRegionLength);
+ shared_region_ = nullptr;
+ fd_.reset();
+ ALOGI("controller disconnected");
+ return OK;
+}
+
+const void* AshmemControllerDataProvider::LockControllerData() {
+ mutex_.lock();
+ if (!shared_region_) {
+ mutex_.unlock();
+ return nullptr;
+ }
+ return shared_region_;
+}
+
+void AshmemControllerDataProvider::UnlockControllerData() { mutex_.unlock(); }
+
+void AshmemControllerDataProvider::dumpInternal(String8& result) {
+ result.appendFormat("[controller]\nfd = %d\n", fd_.get());
+ if (shared_region_) {
+ int32_t* p = reinterpret_cast<int32_t*>(shared_region_);
+ result.appendFormat("header = ");
+ for (int i = 0; i < 8; ++i) {
+ result.appendFormat("%c 0x%08" PRIX32, i ? ',' : '[', p[i]);
+ }
+ result.appendFormat(" ]\n\n");
+ }
+}
+
+int VrWindowManagerBinder::Initialize() { return 0; }
+
+binder::Status VrWindowManagerBinder::connectController(
+ const ::android::base::unique_fd& in_fd) {
+ // TODO(kpschoedel): check permission
+#if 0
+ int32_t pid, uid;
+ if (!PermissionCache::checkCallingPermission(kSendMeControllerInputPermission,
+ &pid, &uid)) {
+ ALOGE("permission denied to pid=%" PRId32 " uid=%" PRId32, pid, uid);
+ return binder::Status::fromStatusT(PERMISSION_DENIED);
+ }
+#endif
+ return binder::Status::fromStatusT(Connect(in_fd.get()));
+}
+
+binder::Status VrWindowManagerBinder::disconnectController() {
+ // TODO(kpschoedel): check permission
+#if 0
+ int32_t pid, uid;
+ if (!PermissionCache::checkCallingPermission(kSendMeControllerInputPermission,
+ &pid, &uid)) {
+ ALOGE("permission denied to pid=%" PRId32 " uid=%" PRId32, pid, uid);
+ return binder::Status::fromStatusT(PERMISSION_DENIED);
+ }
+#endif
+ return binder::Status::fromStatusT(Disconnect());
+}
+
+binder::Status VrWindowManagerBinder::enterVrMode() {
+ // TODO(kpschoedel): check permission
+ app_.VrMode(true);
+ return binder::Status::ok();
+}
+
+binder::Status VrWindowManagerBinder::exitVrMode() {
+ // TODO(kpschoedel): check permission
+ app_.VrMode(false);
+ return binder::Status::ok();
+}
+
+binder::Status VrWindowManagerBinder::setDebugMode(int32_t mode) {
+ // TODO(kpschoedel): check permission
+ app_.EnableDebug(static_cast<bool>(mode));
+ return binder::Status::ok();
+}
+
+status_t VrWindowManagerBinder::dump(
+ int fd, const Vector<String16>& args [[gnu::unused]]) {
+ String8 result;
+ const android::IPCThreadState* ipc = android::IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
+ if ((uid != AID_SHELL) &&
+ !PermissionCache::checkPermission(kDumpPermission, pid, uid)) {
+ result.appendFormat("Permission denial: can't dump " LOG_TAG
+ " from pid=%d, uid=%d\n",
+ pid, uid);
+ } else {
+ app_.dumpInternal(result);
+ AshmemControllerDataProvider::dumpInternal(result);
+ }
+ write(fd, result.string(), result.size());
+ return OK;
+}
+
+} // namespace vr
+} // namespace service
+} // namespace android
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder.h b/services/vr/vr_window_manager/vr_window_manager_binder.h
new file mode 100644
index 0000000..99ca27a
--- /dev/null
+++ b/services/vr/vr_window_manager/vr_window_manager_binder.h
@@ -0,0 +1,77 @@
+#ifndef VR_WINDOW_MANAGER_VR_WINDOW_MANAGER_BINDER_H_
+#define VR_WINDOW_MANAGER_VR_WINDOW_MANAGER_BINDER_H_
+
+#include <android/service/vr/BnVrWindowManager.h>
+
+#include <mutex>
+
+#include "controller_data_provider.h"
+#include "shell_view_binder_interface.h"
+
+namespace android {
+namespace service {
+namespace vr {
+
+class AshmemControllerDataProvider : public dvr::ControllerDataProvider {
+ public:
+ AshmemControllerDataProvider() {}
+ virtual ~AshmemControllerDataProvider() {}
+
+ status_t Connect(int fd);
+ status_t Disconnect();
+
+ // ControllerDataProvider:
+ const void* LockControllerData() override;
+ void UnlockControllerData() override;
+
+ protected:
+ void dumpInternal(String8& result);
+
+ private:
+ static constexpr size_t kRegionLength = 8192; // TODO(kpschoedel)
+ ::android::base::unique_fd fd_;
+
+ // Mutex for guarding shared_region_.
+ std::mutex mutex_;
+ void* shared_region_ = nullptr;
+
+ AshmemControllerDataProvider(const AshmemControllerDataProvider&) = delete;
+ void operator=(const AshmemControllerDataProvider&) = delete;
+};
+
+class VrWindowManagerBinder : public BnVrWindowManager,
+ public AshmemControllerDataProvider {
+ public:
+ VrWindowManagerBinder(android::dvr::ShellViewBinderInterface& app)
+ : app_(app) {}
+ virtual ~VrWindowManagerBinder() {}
+
+ // Must be called before clients can connect.
+ // Returns 0 if initialization is successful.
+ int Initialize();
+ static char const* getServiceName() { return "vr_window_manager"; }
+
+ protected:
+ // Implements IVrWindowManagerBinder.
+ ::android::binder::Status connectController(
+ const ::android::base::unique_fd& fd) override;
+ ::android::binder::Status disconnectController() override;
+ ::android::binder::Status enterVrMode() override;
+ ::android::binder::Status exitVrMode() override;
+ ::android::binder::Status setDebugMode(int32_t mode) override;
+
+ // Implements BBinder::dump().
+ status_t dump(int fd, const Vector<String16>& args) override;
+
+ private:
+ android::dvr::ShellViewBinderInterface& app_;
+
+ VrWindowManagerBinder(const VrWindowManagerBinder&) = delete;
+ void operator=(const VrWindowManagerBinder&) = delete;
+};
+
+} // namespace vr
+} // namespace service
+} // namespace android
+
+#endif // VR_WINDOW_MANAGER_VR_WINDOW_MANAGER_BINDER_H_
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder_test.cpp b/services/vr/vr_window_manager/vr_window_manager_binder_test.cpp
new file mode 100644
index 0000000..f43e803
--- /dev/null
+++ b/services/vr/vr_window_manager/vr_window_manager_binder_test.cpp
@@ -0,0 +1,29 @@
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cutils/log.h>
+
+#include "vr_window_manager_binder.h"
+
+int main() {
+ ALOGI("Starting");
+ android::service::vr::VrWindowManagerBinder service;
+ const int status = service.Initialize();
+ LOG_ALWAYS_FATAL_IF(status != 0, "initialization failed: %d", status);
+
+ signal(SIGPIPE, SIG_IGN);
+ android::sp<android::ProcessState> ps(android::ProcessState::self());
+ ps->setThreadPoolMaxThreadCount(4);
+ ps->startThreadPool();
+ ps->giveThreadPoolName();
+
+ android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+ const android::status_t service_status = sm->addService(
+ android::service::vr::VrWindowManagerBinder::SERVICE_NAME(), &service,
+ false /*allowIsolated*/);
+ LOG_ALWAYS_FATAL_IF(service_status != android::OK, "service not added: %d",
+ static_cast<int>(service_status));
+
+ android::IPCThreadState::self()->joinThreadPool();
+ return 0;
+}
diff --git a/services/vr/vr_window_manager/vr_wm_ctl.cpp b/services/vr/vr_window_manager/vr_wm_ctl.cpp
new file mode 100644
index 0000000..c67b2eb
--- /dev/null
+++ b/services/vr/vr_window_manager/vr_wm_ctl.cpp
@@ -0,0 +1,48 @@
+#include <android/service/vr/BpVrWindowManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <inttypes.h>
+
+void usage() { fprintf(stderr, "usage: vr_wm_ctl [enter|exit|debug N]\n"); }
+
+int report(const android::binder::Status& status) {
+ if (status.isOk()) {
+ fprintf(stderr, "ok\n");
+ return 0;
+ }
+ fprintf(stderr, "failed (%" PRId32 ") %s\n", status.exceptionCode(),
+ status.exceptionMessage().string());
+ return (int)status.exceptionCode();
+}
+
+int main(int argc, char* argv[]) {
+ android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+ if (sm == nullptr) {
+ fprintf(stderr, "service manager not found\n");
+ exit(1);
+ }
+
+ android::sp<android::service::vr::IVrWindowManager> vrwm =
+ android::interface_cast<android::service::vr::IVrWindowManager>(
+ sm->getService(
+ android::service::vr::IVrWindowManager::SERVICE_NAME()));
+ if (vrwm == nullptr) {
+ fprintf(stderr, "service not found\n");
+ exit(1);
+ }
+
+ android::binder::Status status;
+ if ((argc == 2) && (strcmp(argv[1], "enter") == 0)) {
+ exit(report(vrwm->enterVrMode()));
+ } else if ((argc == 2) && (strcmp(argv[1], "exit") == 0)) {
+ exit(report(vrwm->exitVrMode()));
+ } else if ((argc == 3) && (strcmp(argv[1], "debug") == 0)) {
+ exit(report(vrwm->setDebugMode(atoi(argv[2]))));
+ } else {
+ usage();
+ exit(2);
+ }
+
+ return 0;
+}
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 746ab4e..524de75 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -69,12 +69,12 @@
"vulkan_headers",
],
shared_libs: [
- "libgui",
"libziparchive",
"libhardware",
"libsync",
"libbase",
"liblog",
+ "libui",
"libutils",
"libcutils",
"libz",
diff --git a/vulkan/libvulkan/debug_report.cpp b/vulkan/libvulkan/debug_report.cpp
index 0c2f138..40ba1e5 100644
--- a/vulkan/libvulkan/debug_report.cpp
+++ b/vulkan/libvulkan/debug_report.cpp
@@ -46,7 +46,8 @@
Node* prev = &head_;
while (prev && prev->next != node)
prev = prev->next;
- prev->next = node->next;
+ if (prev)
+ prev->next = node->next;
}
allocator.pfnFree(allocator.pUserData, node);
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index b34e9be..991c3ed 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -28,7 +28,7 @@
#include <android/dlext.h>
#include <cutils/properties.h>
-#include <gui/GraphicsEnv.h>
+#include <ui/GraphicsEnv.h>
#include "driver.h"
#include "stubhal.h"
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index d1582d1..f4ee375 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -564,8 +564,8 @@
const VkPresentModeKHR kModes[] = {
VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
// TODO(chrisforbes): should only expose this if the driver can.
- VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,
- VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR,
+ // VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,
+ // VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR,
};
const uint32_t kNumModes = sizeof(kModes) / sizeof(kModes[0]);