Merge "Suppress unnecessary "frame not found" errors."
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 17b411f..af87ffa 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -16,6 +16,7 @@
utils.cpp
COMMON_SHARED_LIBRARIES := \
android.hardware.dumpstate@1.0 \
+ libhidlbase \
libbase \
libbinder \
libcutils \
@@ -102,7 +103,8 @@
LOCAL_MODULE := dumpstate
-LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES) \
+ android.hardware.vibrator@1.0
LOCAL_STATIC_LIBRARIES := $(COMMON_STATIC_LIBRARIES)
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index a0b0426..1e33439 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -43,6 +43,7 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
+#include <android/hardware/vibrator/1.0/IVibrator.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
#include <hardware_legacy/power.h>
@@ -54,6 +55,10 @@
#include "DumpstateService.h"
#include "dumpstate.h"
+using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
+using ::android::hardware::vibrator::V1_0::IVibrator;
+using VibratorStatus = ::android::hardware::vibrator::V1_0::Status;
+
/* read before root is shed */
static char cmdline_buf[16384] = "(unknown)";
static const char *dump_traces_path = NULL;
@@ -1164,8 +1169,8 @@
printf("== Board\n");
printf("========================================================\n");
- android::sp<android::hardware::dumpstate::V1_0::IDumpstateDevice> dumpstate_device(
- android::hardware::dumpstate::V1_0::IDumpstateDevice::getService("DumpstateDevice"));
+ ::android::sp<IDumpstateDevice> dumpstate_device(
+ IDumpstateDevice::getService("DumpstateDevice"));
if (dumpstate_device == nullptr) {
// TODO: temporary workaround until devices on master implement it
MYLOGE("no IDumpstateDevice implementation; using legacy dumpstate_board()\n");
@@ -1586,12 +1591,21 @@
fclose(cmdline);
}
- /* open the vibrator before dropping root */
- std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose);
+ ::android::sp<IVibrator> vibrator = nullptr;
if (do_vibrate) {
- vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we"));
- if (vibrator) {
- vibrate(vibrator.get(), 150);
+ vibrator = IVibrator::getService("vibrator");
+
+ if (vibrator != nullptr) {
+ // cancel previous vibration if any
+ ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
+ if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
+ MYLOGE("Vibrator off failed.");
+ } else {
+ ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(150);
+ if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
+ MYLOGE("Vibrator on failed.");
+ }
+ }
}
}
@@ -1759,10 +1773,20 @@
}
/* vibrate a few but shortly times to let user know it's finished */
- if (vibrator) {
- for (int i = 0; i < 3; i++) {
- vibrate(vibrator.get(), 75);
- usleep((75 + 50) * 1000);
+ if (vibrator != nullptr) {
+ // in case dumpstate magically completes before the above vibration
+ ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
+ if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
+ MYLOGE("Vibrator off failed.");
+ } else {
+ for (int i = 0; i < 3; i++) {
+ ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(75);
+ if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
+ MYLOGE("Vibrator on failed.");
+ break;
+ }
+ usleep((75 + 50) * 1000);
+ }
}
}
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index fcf0683..2c11c0c 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -402,9 +402,6 @@
/* Implemented by libdumpstate_board to dump board-specific info */
void dumpstate_board();
-/* Vibrates for a given durating (in milliseconds). */
-void vibrate(FILE* vibrator, int ms);
-
/* Checks if a given path is a directory. */
bool is_dir(const char* pathname);
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 5ee00c8..ee88705 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -1061,11 +1061,6 @@
}
}
-void vibrate(FILE* vibrator, int ms) {
- fprintf(vibrator, "%d\n", ms);
- fflush(vibrator);
-}
-
bool is_dir(const char* pathname) {
struct stat info;
if (stat(pathname, &info) == -1) {
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 8a9d6a6..81369f9 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -323,8 +323,8 @@
const std::string ref_profile_path = create_data_ref_profile_package_path(pkgname);
// dex2oat/profman runs under the shared app gid and it needs to read/write reference
// profiles.
- appid_t shared_app_gid = multiuser_get_shared_app_gid(uid);
- if (fs_prepare_dir_strict(
+ int shared_app_gid = multiuser_get_shared_app_gid(uid);
+ if ((shared_app_gid != -1) && fs_prepare_dir_strict(
ref_profile_path.c_str(), 0700, shared_app_gid, shared_app_gid) != 0) {
return error("Failed to prepare " + ref_profile_path);
}
diff --git a/include/android/native_window.h b/include/android/native_window.h
index b60b9f1..b017a25 100644
--- a/include/android/native_window.h
+++ b/include/android/native_window.h
@@ -38,12 +38,18 @@
* Pixel formats that a window can use.
*/
enum {
+ // NOTE: these values must match the values from graphics/common/x.x/types.hal
+
/** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/
WINDOW_FORMAT_RGBA_8888 = 1,
/** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Unused: 8 bits. **/
WINDOW_FORMAT_RGBX_8888 = 2,
/** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/
WINDOW_FORMAT_RGB_565 = 4,
+ /** Red: 16 bits, Green: 16 bits, Blue: 16 bits, Alpha: 16 bits. **/
+ WINDOW_FORMAT_RGBA_FP16 = 0x16,
+ /** Red: 16 bits, Green: 16 bits, Blue: 16 bits, Unused: 16 bits. **/
+ WINDOW_FORMAT_RGBX_FP16 = 0x17,
};
struct ANativeWindow;
diff --git a/include/media/hardware/HDCPAPI.h b/include/media/hardware/HDCPAPI.h
index 3a53e9f..30cd5fd 100644
--- a/include/media/hardware/HDCPAPI.h
+++ b/include/media/hardware/HDCPAPI.h
@@ -73,7 +73,7 @@
// Module can call the notification function to signal completion/failure
// of asynchronous operations (such as initialization) or out of band
// events.
- HDCPModule(void *cookie, ObserverFunc observerNotify) {};
+ HDCPModule(void * /*cookie*/, ObserverFunc /*observerNotify*/) {};
virtual ~HDCPModule() {};
@@ -104,8 +104,8 @@
// 1 for the second and so on)
// inputCTR _will_be_maintained_by_the_callee_ for each PES stream.
virtual status_t encrypt(
- const void *inData, size_t size, uint32_t streamCTR,
- uint64_t *outInputCTR, void *outData) {
+ const void * /*inData*/, size_t /*size*/, uint32_t /*streamCTR*/,
+ uint64_t * /*outInputCTR*/, void * /*outData*/) {
return INVALID_OPERATION;
}
@@ -119,8 +119,8 @@
// 1 for the second and so on)
// inputCTR _will_be_maintained_by_the_callee_ for each PES stream.
virtual status_t encryptNative(
- buffer_handle_t buffer, size_t offset, size_t size,
- uint32_t streamCTR, uint64_t *outInputCTR, void *outData) {
+ buffer_handle_t /*buffer*/, size_t /*offset*/, size_t /*size*/,
+ uint32_t /*streamCTR*/, uint64_t * /*outInputCTR*/, void * /*outData*/) {
return INVALID_OPERATION;
}
// DECRYPTION only:
@@ -133,9 +133,9 @@
// until outData contains size bytes of decrypted data.
// Both streamCTR and inputCTR will be provided by the caller.
virtual status_t decrypt(
- const void *inData, size_t size,
- uint32_t streamCTR, uint64_t inputCTR,
- void *outData) {
+ const void * /*inData*/, size_t /*size*/,
+ uint32_t /*streamCTR*/, uint64_t /*inputCTR*/,
+ void * /*outData*/) {
return INVALID_OPERATION;
}
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index f26fecb..99c6663 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -60,6 +60,8 @@
PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA
PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB
PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB
+ PIXEL_FORMAT_RGBA_FP16 = HAL_PIXEL_FORMAT_RGBA_FP16, // 64-bit RGBA
+ PIXEL_FORMAT_RGBX_FP16 = HAL_PIXEL_FORMAT_RGBX_FP16, // 64-bit RGB0
};
typedef int32_t PixelFormat;
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index 8393160..4acf618 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -64,6 +64,8 @@
switch (static_cast<int>(format)) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_FP16:
+ case HAL_PIXEL_FORMAT_RGBX_FP16:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGRA_8888:
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 316e1d6..b919b3c 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -858,6 +858,8 @@
switch (buf->getPixelFormat()) {
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
+ case PIXEL_FORMAT_RGBA_FP16:
+ case PIXEL_FORMAT_RGBX_FP16:
case PIXEL_FORMAT_RGB_888:
case PIXEL_FORMAT_RGB_565:
case PIXEL_FORMAT_BGRA_8888:
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 1aa03a5..66e1bb6 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -29,8 +29,12 @@
#include <private/gui/ComposerService.h>
#include <binder/ProcessState.h>
+#include <thread>
+
namespace android {
+using namespace std::chrono_literals;
+
class SurfaceTest : public ::testing::Test {
protected:
@@ -77,6 +81,8 @@
TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) {
mSurfaceControl.clear();
+ // Wait for the async clean-up to complete.
+ std::this_thread::sleep_for(50ms);
sp<ANativeWindow> anw(mSurface);
int result = -123;
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index cab1dde..3ceb638 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -22,6 +22,9 @@
uint32_t bytesPerPixel(PixelFormat format) {
switch (format) {
+ case PIXEL_FORMAT_RGBA_FP16:
+ case PIXEL_FORMAT_RGBX_FP16:
+ return 8;
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
case PIXEL_FORMAT_BGRA_8888:
@@ -38,6 +41,9 @@
uint32_t bitsPerPixel(PixelFormat format) {
switch (format) {
+ case PIXEL_FORMAT_RGBA_FP16:
+ case PIXEL_FORMAT_RGBX_FP16:
+ return 64;
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
case PIXEL_FORMAT_BGRA_8888:
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 73e5e07..874e712 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -643,8 +643,8 @@
EGLAPI EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
EGLAPI EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
#else
-typedef EGLAPI EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
-typedef EGLAPI EGLBoolean (EGLAPIENTRYP PFNEGLQUERYTIMESTAMPSUPPORTEDANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYTIMESTAMPSUPPORTEDANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
#endif
#endif
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 71538d6..6328c9c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -476,6 +476,7 @@
// modify the EGLconfig's format before setting the native window's
// format.
+ // TODO: Add support for HAL_PIXEL_FORMAT_RGBA_FP16
// by default, just pick RGBA_8888
EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 7b47709..2e44736 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -868,7 +868,7 @@
}
}
-Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
+Vector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) {
char value[PROPERTY_VALUE_MAX];
property_get("debug.sensors", value, "0");
const Vector<Sensor>& initialSensorList = (atoi(value)) ?
@@ -876,14 +876,7 @@
Vector<Sensor> accessibleSensorList;
for (size_t i = 0; i < initialSensorList.size(); i++) {
Sensor sensor = initialSensorList[i];
- if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
- accessibleSensorList.add(sensor);
- } else {
- ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
- sensor.getName().string(),
- sensor.getRequiredPermission().string(),
- sensor.getRequiredAppOp());
- }
+ accessibleSensorList.add(sensor);
}
makeUuidsIntoIdsForSensorList(accessibleSensorList);
return accessibleSensorList;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 33fb8cb..7e8f94b 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -57,6 +57,8 @@
typedef std::function<void(std::shared_ptr<Display>)> RefreshCallback;
typedef std::function<void(std::shared_ptr<Display>, nsecs_t)> VsyncCallback;
+// C++ Wrapper around hwc2_device_t. Load all functions pointers
+// and handle callback registration.
class Device
{
public:
@@ -207,6 +209,7 @@
std::vector<std::pair<std::shared_ptr<Display>, nsecs_t>> mPendingVsyncs;
};
+// Convenience C++ class to access hwc2_device_t Display functions directly.
class Display : public std::enable_shared_from_this<Display>
{
public:
@@ -368,6 +371,7 @@
std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
};
+// Convenience C++ class to access hwc2_device_t Layer functions directly.
class Layer
{
public:
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 1727bd6..c4f845d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -86,6 +86,7 @@
for (size_t l = 0; l < contents->numHwLayers; ++l) {
auto& layer = contents->hwLayers[l];
std::free(const_cast<hwc_rect_t*>(layer.visibleRegionScreen.rects));
+ std::free(const_cast<hwc_rect_t*>(layer.surfaceDamage.rects));
}
}
std::free(contents);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
index aa96004..9abdc38 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
@@ -40,6 +40,10 @@
namespace android {
+// For devices unable to provide an implementation of HWC2 (see hwcomposer2.h),
+// we provide an adapter able to talk to HWC1 (see hwcomposer.h). It translates
+// streamed function calls ala HWC2 model to batched array of structs calls ala
+// HWC1 model.
class HWC2On1Adapter : public hwc2_device_t
{
public:
@@ -135,6 +139,24 @@
void operator()(struct hwc_display_contents_1* contents);
};
+ // The semantics of the fences returned by the device differ between
+ // hwc1.set() and hwc2.present(). Read hwcomposer.h and hwcomposer2.h
+ // for more information.
+ //
+ // Release fences in hwc1 are obtained on set() for a frame n and signaled
+ // when the layer buffer is not needed for read operations anymore
+ // (typically on frame n+1). In HWC2, release fences are obtained with a
+ // special call after present() for frame n. These fences signal
+ // on frame n: More specifically, the fence for a given buffer provided in
+ // frame n will signal when the prior buffer is no longer required.
+ //
+ // A retire fence (HWC1) is signaled when a composition is replaced
+ // on the panel whereas a present fence (HWC2) is signaled when a
+ // composition starts to be displayed on a panel.
+ //
+ // The HWC2to1Adapter emulates the new fence semantics for a frame
+ // n by returning the fence from frame n-1. For frame 0, the adapter
+ // returns NO_FENCE.
class DeferredFence {
public:
DeferredFence()
@@ -150,6 +172,7 @@
}
private:
+ // There are always two fences in this queue.
std::queue<sp<Fence>> mFences;
};
@@ -234,7 +257,10 @@
bool prepare();
HWC1Contents cloneRequestedContents() const;
+
+ // Called after hwc.prepare() with responses from the device.
void setReceivedContents(HWC1Contents contents);
+
bool hasChanges() const;
HWC2::Error set(hwc_display_contents_1& hwcContents);
void addRetireFence(int fenceFd);
@@ -288,6 +314,10 @@
std::unordered_map<android_color_mode_t, uint32_t> mHwc1Ids;
};
+ // Store changes requested from the device upon calling prepare().
+ // Handles change request to:
+ // - Layer composition type.
+ // - Layer hints.
class Changes {
public:
uint32_t getNumTypes() const {
@@ -336,8 +366,13 @@
void reallocateHwc1Contents();
void assignHwc1LayerIds();
+ // Called after a response to prepare() has been received:
+ // Ingest composition type changes requested by the device.
void updateTypeChanges(const struct hwc_layer_1& hwc1Layer,
const Layer& layer);
+
+ // Called after a response to prepare() has been received:
+ // Ingest layer hint changes requested by the device.
void updateLayerRequests(const struct hwc_layer_1& hwc1Layer,
const Layer& layer);
@@ -361,8 +396,11 @@
mutable std::recursive_mutex mStateMutex;
bool mZIsDirty;
- HWC1Contents mHwc1RequestedContents;
- HWC1Contents mHwc1ReceivedContents;
+
+ // Array of structs exchanged between client and hwc1 device.
+ HWC1Contents mHwc1RequestedContents; // Sent to device upon calling prepare().
+ HWC1Contents mHwc1ReceivedContents; // Returned by device after prepare().
+
DeferredFence mRetireFence;
// Will only be non-null after the layer has been validated but
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
index 2102457..c40a58c 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -1159,6 +1159,8 @@
switch (format) {
case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888");
case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888");
+ case PIXEL_FORMAT_RGBA_FP16: return String8("RGBA_FP16");
+ case PIXEL_FORMAT_RGBX_FP16: return String8("RGBx_FP16");
case PIXEL_FORMAT_RGB_888: return String8("RGB_888");
case PIXEL_FORMAT_RGB_565: return String8("RGB_565");
case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888");
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 395757b..c7d37a5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -972,7 +972,7 @@
} else {
engine.setupLayerBlackedOut();
}
- drawWithOpenGL(hw, clip, useIdentityTransform);
+ drawWithOpenGL(hw, useIdentityTransform);
engine.disableTexturing();
}
@@ -993,7 +993,7 @@
}
void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
- const Region& /* clip */, bool useIdentityTransform) const {
+ bool useIdentityTransform) const {
const State& s(getDrawingState());
computeGeometry(hw, mMesh, useIdentityTransform);
@@ -1189,6 +1189,7 @@
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_FP16:
return false;
}
// in all other case, we have no blending (also for unknown formats)
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 612fb0d..b1e3298 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -464,7 +464,7 @@
// drawing
void clearWithOpenGL(const sp<const DisplayDevice>& hw,
float r, float g, float b, float alpha) const;
- void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
+ void drawWithOpenGL(const sp<const DisplayDevice>& hw,
bool useIdentityTransform) const;
// Temporary - Used only for LEGACY camera mode.
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index 359ca4e..8bf6e82 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -49,7 +49,7 @@
wp<IBinder> mProducer;
};
- mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder(this)));
+ mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder(mProducer)));
}
status_t MonitoredProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
@@ -156,7 +156,7 @@
}
IBinder* MonitoredProducer::onAsBinder() {
- return IInterface::asBinder(mProducer).get();
+ return this;
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index 17adaa7..becc740 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -27,7 +27,7 @@
// MonitoredProducer wraps an IGraphicBufferProducer so that SurfaceFlinger will
// be notified upon its destruction
-class MonitoredProducer : public IGraphicBufferProducer {
+class MonitoredProducer : public BnGraphicBufferProducer {
public:
MonitoredProducer(const sp<IGraphicBufferProducer>& producer,
const sp<SurfaceFlinger>& flinger);
diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h
index ddbb311..16a43b6 100644
--- a/vulkan/include/vulkan/vulkan.h
+++ b/vulkan/include/vulkan/vulkan.h
@@ -218,6 +218,7 @@
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
+ VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
@@ -3715,6 +3716,27 @@
#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1
#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge"
+#define VK_KHR_incremental_present 1
+#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1
+#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present"
+
+typedef struct VkRectLayerKHR {
+ VkOffset2D offset;
+ VkExtent2D extent;
+ uint32_t layer;
+} VkRectLayerKHR;
+
+typedef struct VkPresentRegionKHR {
+ uint32_t rectangleCount;
+ const VkRectLayerKHR* pRectangles;
+} VkPresentRegionKHR;
+
+typedef struct VkPresentRegionsKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const VkPresentRegionKHR* pRegions;
+} VkPresentRegionsKHR;
#define VK_EXT_debug_report 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 63c597c..9856d6a 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -723,6 +723,8 @@
const VkAllocationCallbacks* allocator) {
const auto& dispatch = GetData(device).driver;
Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
+ if (!swapchain)
+ return;
bool active = swapchain->surface.swapchain_handle == swapchain_handle;
ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr;
@@ -860,17 +862,43 @@
ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
"vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d",
present_info->sType);
- ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL");
VkDevice device = GetData(queue).driver_device;
const auto& dispatch = GetData(queue).driver;
VkResult final_result = VK_SUCCESS;
+ // Look at the pNext chain for supported extension structs:
+ const VkPresentRegionsKHR* present_regions = NULL;
+ const VkPresentRegionsKHR* next =
+ reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext);
+ while (next) {
+ switch (next->sType) {
+ case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR:
+ present_regions = next;
+ break;
+ default:
+ ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x",
+ next->sType);
+ break;
+ }
+ next = reinterpret_cast<const VkPresentRegionsKHR*>(next->pNext);
+ }
+ ALOGV_IF(
+ present_regions &&
+ present_regions->swapchainCount != present_info->swapchainCount,
+ "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount");
+ const VkPresentRegionKHR* regions =
+ (present_regions) ? present_regions->pRegions : NULL;
+ const VkAllocationCallbacks* allocator = &GetData(device).allocator;
+ android_native_rect_t* rects = NULL;
+ uint32_t nrects = 0;
+
for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) {
Swapchain& swapchain =
*SwapchainFromHandle(present_info->pSwapchains[sc]);
uint32_t image_idx = present_info->pImageIndices[sc];
Swapchain::Image& img = swapchain.images[image_idx];
+ const VkPresentRegionKHR* region = (regions) ? ®ions[sc] : NULL;
VkResult swapchain_result = VK_SUCCESS;
VkResult result;
int err;
@@ -888,6 +916,45 @@
present_info->pSwapchains[sc]) {
ANativeWindow* window = swapchain.surface.window.get();
if (swapchain_result == VK_SUCCESS) {
+ if (region) {
+ // Process the incremental-present hint for this swapchain:
+ uint32_t rcount = region->rectangleCount;
+ if (rcount > nrects) {
+ android_native_rect_t* new_rects =
+ static_cast<android_native_rect_t*>(
+ allocator->pfnReallocation(
+ allocator->pUserData, rects,
+ sizeof(android_native_rect_t) * rcount,
+ alignof(android_native_rect_t),
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
+ if (new_rects) {
+ rects = new_rects;
+ nrects = rcount;
+ } else {
+ rcount = 0; // Ignore the hint for this swapchain
+ }
+ }
+ for (uint32_t r = 0; r < rcount; ++r) {
+ if (region->pRectangles[r].layer > 0) {
+ ALOGV(
+ "vkQueuePresentKHR ignoring invalid layer "
+ "(%u); using layer 0 instead",
+ region->pRectangles[r].layer);
+ }
+ int x = region->pRectangles[r].offset.x;
+ int y = region->pRectangles[r].offset.y;
+ int width = static_cast<int>(
+ region->pRectangles[r].extent.width);
+ int height = static_cast<int>(
+ region->pRectangles[r].extent.height);
+ android_native_rect_t* cur_rect = &rects[r];
+ cur_rect->left = x;
+ cur_rect->top = y + height;
+ cur_rect->right = x + width;
+ cur_rect->bottom = y;
+ }
+ native_window_set_surface_damage(window, rects, rcount);
+ }
err = window->queueBuffer(window, img.buffer.get(), fence);
// queueBuffer always closes fence, even on error
if (err != 0) {
@@ -918,6 +985,9 @@
if (swapchain_result != final_result)
final_result = WorstPresentResult(final_result, swapchain_result);
}
+ if (rects) {
+ allocator->pfnFree(allocator->pUserData, rects);
+ }
return final_result;
}