Merge "Add android.hardware.vulkan.compute=0 feature file"
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index 69ed416..225de20 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -16,6 +16,9 @@
"libz",
"libbase",
],
+ static_libs: [
+ "libpdx_default_transport",
+ ],
init_rc: ["atrace.rc"],
}
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 4be0432..ce0caed 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -18,6 +18,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <ftw.h>
#include <getopt.h>
#include <inttypes.h>
#include <signal.h>
@@ -41,6 +42,7 @@
#include <hidl/ServiceManagement.h>
#include <cutils/properties.h>
+#include <pdx/default_transport/service_utility.h>
#include <utils/String8.h>
#include <utils/Timers.h>
#include <utils/Tokenizer.h>
@@ -48,6 +50,7 @@
#include <android-base/file.h>
using namespace android;
+using pdx::default_transport::ServiceUtility;
using std::string;
#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
@@ -569,6 +572,46 @@
}
}
+// Sends the sysprop_change message to the service at fpath, so it re-reads its
+// system properties. Returns 0 on success or a negated errno code on failure.
+static int pokeOnePDXService(const char *fpath, const struct stat * /*sb*/,
+ int typeflag, struct FTW * /*ftwbuf*/)
+{
+ const bool kIgnoreErrors = true;
+
+ if (typeflag == FTW_F) {
+ int error;
+ auto utility = ServiceUtility::Create(fpath, &error);
+ if (!utility) {
+ if (error != -ECONNREFUSED) {
+ ALOGE("pokeOnePDXService: Failed to open %s, %s.", fpath,
+ strerror(-error));
+ }
+ return kIgnoreErrors ? 0 : error;
+ }
+
+ auto status = utility->ReloadSystemProperties();
+ if (!status) {
+ ALOGE("pokeOnePDXService: Failed to send sysprop change to %s, "
+ "error %d, %s.", fpath, status.error(),
+ status.GetErrorMessage().c_str());
+ return kIgnoreErrors ? 0 : -status.error();
+ }
+ }
+
+ return 0;
+}
+
+// Pokes all the PDX processes in the system to get them to re-read
+// their system properties. Returns true on success, false on failure.
+static bool pokePDXServices()
+{
+ const int kMaxDepth = 16;
+ const int result = nftw(ServiceUtility::GetRootEndpointPath().c_str(),
+ pokeOnePDXService, kMaxDepth, FTW_PHYS);
+ return result == 0 ? true : false;
+}
+
// Set the trace tags that userland tracing uses, and poke the running
// processes to pick up the new value.
static bool setTagsProperty(uint64_t tags)
@@ -812,6 +855,7 @@
ok &= setAppCmdlineProperty(&packageList[0]);
ok &= pokeBinderServices();
pokeHalServices();
+ ok &= pokePDXServices();
// Disable all the sysfs enables. This is done as a separate loop from
// the enables to allow the same enable to exist in multiple categories.
@@ -849,6 +893,7 @@
setTagsProperty(0);
clearAppProperties();
pokeBinderServices();
+ pokePDXServices();
// Set the options back to their defaults.
setTraceOverwriteEnable(true);
diff --git a/include/audiomanager/IPlayer.h b/include/audiomanager/IPlayer.h
index efcac74..94afae5 100644
--- a/include/audiomanager/IPlayer.h
+++ b/include/audiomanager/IPlayer.h
@@ -41,6 +41,10 @@
virtual void setVolume(float vol) = 0;
+ virtual void setPan(float pan) = 0;
+
+ virtual void setStartDelayMs(int delayMs) = 0;
+
};
// ----------------------------------------------------------------------------
diff --git a/libs/vr/libeds/distortion_renderer.cpp b/libs/vr/libeds/distortion_renderer.cpp
index 59029d8..13090ca 100644
--- a/libs/vr/libeds/distortion_renderer.cpp
+++ b/libs/vr/libeds/distortion_renderer.cpp
@@ -308,7 +308,7 @@
if (blend_with_previous_layer) {
// Check for unsupported shader combinations:
LOG_ALWAYS_FATAL_IF(num_layers != 1);
- LOG_ALWAYS_FATAL_IF(!use_alpha_vignette);
+ LOG_ALWAYS_FATAL_IF(use_alpha_vignette);
if (kUseFramebufferReadback)
frag_builder += "#define BLEND_WITH_PREVIOUS_LAYER\n";
}
diff --git a/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so b/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so
index 1d0ba50..bfd5956 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so b/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so
index 905ca64..c3012b1 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so b/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so
index d62f7ca..6608c25 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so b/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so
index e342f6a..b1d7690 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so b/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so
index 8092138..f7f7786 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so b/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so
index 3fe5b2c..97aec40 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so b/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so
index 3bcf60e..2e2dbc1 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so b/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so
index 2f2d834..cd8d0e0 100644
--- a/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so
+++ b/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so
Binary files differ
diff --git a/libs/vr/libgvr/prebuilt/lib/common_library.aar b/libs/vr/libgvr/prebuilt/lib/common_library.aar
index 13147fe..9c1fbd0 100644
--- a/libs/vr/libgvr/prebuilt/lib/common_library.aar
+++ b/libs/vr/libgvr/prebuilt/lib/common_library.aar
Binary files differ
diff --git a/libs/vr/libgvr/shim_gvr.cpp b/libs/vr/libgvr/shim_gvr.cpp
index fa8a655..5eb6e3d 100644
--- a/libs/vr/libgvr/shim_gvr.cpp
+++ b/libs/vr/libgvr/shim_gvr.cpp
@@ -512,7 +512,8 @@
}
bool gvr_is_feature_supported(const gvr_context* /*gvr*/, int32_t feature) {
- return feature == GVR_FEATURE_ASYNC_REPROJECTION;
+ return feature == GVR_FEATURE_ASYNC_REPROJECTION ||
+ feature == GVR_FEATURE_HEAD_POSE_6DOF;
}
/////////////////////////////////////////////////////////////////////////////
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index e0b592e..cc08209 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -211,11 +211,15 @@
layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
}
+#if ENABLE_BACKLIGHT_BRIGHTNESS
+ // TODO(hendrikw): This isn't required at the moment. It's possible that there
+ // is another method to access this when needed.
// Open the backlight brightness control sysfs node.
backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
ALOGW_IF(!backlight_brightness_fd_,
"HardwareComposer: Failed to open backlight brightness control: %s",
strerror(errno));
+#endif // ENABLE_BACKLIGHT_BRIGHTNESS
// Open the vsync event node for the primary display.
// TODO(eieio): Move this into a platform-specific class.
diff --git a/services/audiomanager/IPlayer.cpp b/services/audiomanager/IPlayer.cpp
index 3b0b4e9..47edc4b 100644
--- a/services/audiomanager/IPlayer.cpp
+++ b/services/audiomanager/IPlayer.cpp
@@ -33,6 +33,8 @@
PAUSE = IBinder::FIRST_CALL_TRANSACTION + 1,
STOP = IBinder::FIRST_CALL_TRANSACTION + 2,
SET_VOLUME = IBinder::FIRST_CALL_TRANSACTION + 3,
+ SET_PAN = IBinder::FIRST_CALL_TRANSACTION + 4,
+ SET_START_DELAY_MS = IBinder::FIRST_CALL_TRANSACTION + 5,
};
class BpPlayer : public BpInterface<IPlayer>
@@ -71,6 +73,21 @@
data.writeFloat(vol);
remote()->transact(SET_VOLUME, data, &reply);
}
+
+ virtual void setPan(float pan)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+ data.writeFloat(pan);
+ remote()->transact(SET_PAN, data, &reply);
+ }
+
+ virtual void setStartDelayMs(int32_t delayMs) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+ data.writeInt32(delayMs);
+ remote()->transact(SET_START_DELAY_MS, data, &reply);
+ }
};
IMPLEMENT_META_INTERFACE(Player, "android.media.IPlayer");
@@ -100,7 +117,17 @@
CHECK_INTERFACE(IPlayer, data, reply);
setVolume(data.readFloat());
return NO_ERROR;
- }
+ } break;
+ case SET_PAN: {
+ CHECK_INTERFACE(IPlayer, data, reply);
+ setPan(data.readFloat());
+ return NO_ERROR;
+ } break;
+ case SET_START_DELAY_MS: {
+ CHECK_INTERFACE(IPlayer, data, reply);
+ setStartDelayMs(data.readInt32());
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 37de7a2..2b603cc 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -1298,6 +1298,7 @@
auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
hwc1Layer.releaseFenceFd = -1;
hwc1Layer.acquireFenceFd = -1;
+ ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
layer->applyState(hwc1Layer, applyAllState);
}
@@ -2009,7 +2010,6 @@
mZ(0),
mReleaseFence(),
mHwc1Id(0),
- mHasUnsupportedDataspace(false),
mHasUnsupportedPlaneAlpha(false) {}
bool HWC2On1Adapter::SortLayersByZ::operator()(
@@ -2070,9 +2070,8 @@
return Error::None;
}
-Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t dataspace)
+Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t)
{
- mHasUnsupportedDataspace = (dataspace != HAL_DATASPACE_UNKNOWN);
return Error::None;
}
@@ -2318,8 +2317,13 @@
// HWC1 never supports color transforms or dataspaces and only sometimes
// supports plane alpha (depending on the version). These require us to drop
// some or all layers to client composition.
- if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
- mDisplay.hasColorTransform() || mHasUnsupportedBackgroundColor) {
+ ALOGV("applyCompositionType");
+ ALOGV("mHasUnsupportedPlaneAlpha = %d", mHasUnsupportedPlaneAlpha);
+ ALOGV("mDisplay.hasColorTransform() = %d", mDisplay.hasColorTransform());
+ ALOGV("mHasUnsupportedBackgroundColor = %d", mHasUnsupportedBackgroundColor);
+
+ if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
+ mHasUnsupportedBackgroundColor) {
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags = HWC_SKIP_LAYER;
return;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
index 9abdc38..df33ec3 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
@@ -605,7 +605,6 @@
DeferredFence mReleaseFence;
size_t mHwc1Id;
- bool mHasUnsupportedDataspace;
bool mHasUnsupportedPlaneAlpha;
bool mHasUnsupportedBackgroundColor;
};
diff --git a/services/vr/vr_window_manager/application.cpp b/services/vr/vr_window_manager/application.cpp
index b4568b8..62db639 100644
--- a/services/vr/vr_window_manager/application.cpp
+++ b/services/vr/vr_window_manager/application.cpp
@@ -161,8 +161,10 @@
}
break;
case MainThreadTask::EnteringVrMode:
- if (!initialized_)
- AllocateResources();
+ if (!initialized_) {
+ if (AllocateResources())
+ ALOGE("Failed to allocate resources");
+ }
break;
case MainThreadTask::ExitingVrMode:
if (initialized_)
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 53c7d8e..f83fa86 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -142,36 +142,48 @@
}
}
-std::vector<ComposerView::ComposerLayer> HwcDisplay::GetFrame() {
- // Increment the time the fence is signalled every time we get the
- // presentation frame. This ensures that calling ReleaseFrame() only affects
- // the current frame.
- fence_time_++;
-
+Error HwcDisplay::GetFrame(
+ std::vector<ComposerView::ComposerLayer>* out_frames) {
bool queued_client_target = false;
std::vector<ComposerView::ComposerLayer> frame;
for (const auto& layer : layers_) {
if (layer.composition_type == IComposerClient::Composition::CLIENT) {
- if (!queued_client_target) {
- ComposerView::ComposerLayer client_target_layer = {
- .buffer = buffer_,
- .fence = fence_.get() ? fence_ : new Fence(-1),
- .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
- static_cast<int32_t>(buffer_->getHeight())},
- .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
- static_cast<float>(buffer_->getHeight())},
- .blend_mode = IComposerClient::BlendMode::NONE,
- };
+ if (queued_client_target)
+ continue;
- frame.push_back(client_target_layer);
- queued_client_target = true;
+ if (!buffer_.get()) {
+ ALOGE("Client composition requested but no client target buffer");
+ return Error::BAD_LAYER;
}
+
+ ComposerView::ComposerLayer client_target_layer = {
+ .buffer = buffer_,
+ .fence = fence_.get() ? fence_ : new Fence(-1),
+ .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
+ static_cast<int32_t>(buffer_->getHeight())},
+ .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
+ static_cast<float>(buffer_->getHeight())},
+ .blend_mode = IComposerClient::BlendMode::NONE,
+ };
+
+ frame.push_back(client_target_layer);
+ queued_client_target = true;
} else {
+ if (!layer.info.buffer.get() || !layer.info.fence.get()) {
+ ALOGE("Layer requested without valid buffer");
+ return Error::BAD_LAYER;
+ }
+
frame.push_back(layer.info);
}
}
- return frame;
+ // Increment the time the fence is signalled every time we get the
+ // presentation frame. This ensures that calling ReleaseFrame() only affects
+ // the current frame.
+ fence_time_++;
+ out_frames->swap(frame);
+ return Error::NONE;
}
void HwcDisplay::GetReleaseFences(int* present_fence,
@@ -392,7 +404,8 @@
base::unique_fd fence(releaseFence);
if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
- return Error::NONE;
+ ALOGE("Virtual display support not implemented");
+ return Error::UNSUPPORTED;
}
Error VrHwc::validateDisplay(
@@ -423,7 +436,10 @@
std::vector<ComposerView::ComposerLayer> frame;
{
std::lock_guard<std::mutex> guard(mutex_);
- frame = display_.GetFrame();
+ Error status = display_.GetFrame(&frame);
+ if (status != Error::NONE)
+ return status;
+
display_.GetReleaseFences(outPresentFence, outLayers, outReleaseFences);
}
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 1de056a..6b9487b 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -115,7 +115,7 @@
std::vector<Layer>* layer_ids,
std::vector<IComposerClient::Composition>* composition);
- std::vector<ComposerView::ComposerLayer> GetFrame();
+ Error GetFrame(std::vector<ComposerView::ComposerLayer>* out_frame);
void GetReleaseFences(int* present_fence, std::vector<Layer>* layer_ids,
std::vector<int>* fences);
diff --git a/services/vr/vr_window_manager/hwc_callback.cpp b/services/vr/vr_window_manager/hwc_callback.cpp
index b2edc20..5045790 100644
--- a/services/vr/vr_window_manager/hwc_callback.cpp
+++ b/services/vr/vr_window_manager/hwc_callback.cpp
@@ -79,8 +79,7 @@
}
std::lock_guard<std::mutex> guard(mutex_);
- if (client_)
- client_->OnFrame(std::make_unique<Frame>(std::move(hwc_frame)));
+ client_->OnFrame(std::make_unique<Frame>(std::move(hwc_frame)));
return Void();
}
diff --git a/services/vr/vr_window_manager/render_thread.cpp b/services/vr/vr_window_manager/render_thread.cpp
index 5f777e3..b67a051 100644
--- a/services/vr/vr_window_manager/render_thread.cpp
+++ b/services/vr/vr_window_manager/render_thread.cpp
@@ -75,7 +75,6 @@
jobject android_context = env->NewLocalRef(android_context_global_ref_);
int init_result = shell_view_.Initialize(env, android_context, class_loader);
- init_result += shell_view_.AllocateResources();
init_result_promise->set_value(init_result);
if (init_result == 0) {
while (!quit_)
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index ca49db7..11680af 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -15,6 +15,8 @@
namespace {
+constexpr float kLayerScaleFactor = 4.0f;
+
constexpr unsigned int kVRAppLayerCount = 2;
constexpr unsigned int kMaximumPendingFrames = 8;
@@ -105,6 +107,9 @@
else
xscale = ar;
+ xscale *= kLayerScaleFactor;
+ yscale *= kLayerScaleFactor;
+
return mat4(Eigen::Scaling<float>(xscale, yscale, 1.0));
}
@@ -126,7 +131,7 @@
m(3, 0) = 0.0f; m(3, 1) = 0.0f; m(3, 2) = 0.0f; m(3, 3) = 1.0f;
// clang-format on
- return m;
+ return m * Eigen::AngleAxisf(M_PI * 0.5f, vec3::UnitZ());
}
// Helper function that applies the crop transform to the texture layer and
@@ -194,16 +199,22 @@
}
// Determine if ths frame should be shown or hidden.
-bool CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
- uint32_t vr_app) {
+ViewMode CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
+ uint32_t vr_app) {
auto& layers = frame.layers();
// We assume the first two layers are the VR app.
if (layers.size() < kVRAppLayerCount)
- return false;
+ return ViewMode::Hidden;
- if (vr_app != layers[0].appid || layers[0].appid == 0)
- return false;
+ if (vr_app != layers[0].appid || layers[0].appid == 0 ||
+ layers[1].appid != layers[0].appid) {
+ if (layers[1].appid != layers[0].appid && layers[0].appid) {
+ // This might be a 2D app.
+ return ViewMode::App;
+ }
+ return ViewMode::Hidden;
+ }
// If a non-VR-app, non-skipped layer appears, show.
size_t index = kVRAppLayerCount;
@@ -219,11 +230,12 @@
// If any non-skipped layers exist now then we show, otherwise hide.
for (size_t i = index; i < layers.size(); i++) {
if (!layers[i].should_skip_layer())
- return true;
+ return ViewMode::VR;
}
- return false;
+ return ViewMode::Hidden;
}
+
} // namespace
ShellView::ShellView() {
@@ -245,6 +257,10 @@
if (!InitializeTouch())
ALOGE("Failed to initialize virtual touchpad");
+ surface_flinger_view_.reset(new SurfaceFlingerView);
+ if (!surface_flinger_view_->Initialize(this))
+ return 1;
+
return 0;
}
@@ -262,10 +278,6 @@
if (!program_ || !overlay_program_ || !controller_program_)
return 1;
- surface_flinger_view_.reset(new SurfaceFlingerView);
- if (!surface_flinger_view_->Initialize(this))
- return 1;
-
reticle_.reset(new Reticle());
if (!reticle_->Initialize())
return 1;
@@ -299,34 +311,45 @@
: MainThreadTask::ExitingVrMode);
}
+void ShellView::AdvanceFrame() {
+ if (!pending_frames_.empty()) {
+ // Check if we should advance the frame.
+ auto& frame = pending_frames_.front();
+ if (frame.visibility == ViewMode::Hidden ||
+ frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
+ current_frame_ = std::move(frame);
+ pending_frames_.pop_front();
+
+ for(int i = 0; i < skipped_frame_count_ + 1; i++)
+ surface_flinger_view_->ReleaseFrame();
+ skipped_frame_count_ = 0;
+ }
+ }
+}
+
void ShellView::OnDrawFrame() {
textures_.clear();
has_ime_ = false;
{
std::unique_lock<std::mutex> l(pending_frame_mutex_);
- if (!pending_frames_.empty()) {
- // Check if we should advance the frame.
- auto& frame = pending_frames_.front();
- if (!frame.visibility ||
- frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
- current_frame_ = std::move(frame);
- pending_frames_.pop_front();
- }
- }
+ AdvanceFrame();
}
- if (!debug_mode_ && current_frame_.visibility != is_visible_) {
- SetVisibility(current_frame_.visibility);
+ bool visible = current_frame_.visibility != ViewMode::Hidden;
+
+ if (!debug_mode_ && visible != is_visible_) {
+ SetVisibility(current_frame_.visibility != ViewMode::Hidden);
}
- if (!current_frame_.visibility)
+ if (!debug_mode_ && !visible)
return;
ime_texture_ = TextureLayer();
surface_flinger_view_->GetTextures(*current_frame_.frame.get(), &textures_,
- &ime_texture_, debug_mode_);
+ &ime_texture_, debug_mode_,
+ current_frame_.visibility == ViewMode::VR);
has_ime_ = ime_texture_.texture != nullptr;
}
@@ -370,33 +393,35 @@
}
void ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {
- if (!frame || frame->layers().empty())
- return;
+ ViewMode visibility =
+ CalculateVisibilityFromLayerConfig(*frame.get(), current_vr_app_);
- bool visibility = debug_mode_ || CalculateVisibilityFromLayerConfig(
- *frame.get(), current_vr_app_);
+ if (visibility == ViewMode::Hidden && debug_mode_)
+ visibility = ViewMode::VR;
current_vr_app_ = frame->layers().front().appid;
- // If we are not showing the frame there's no need to keep anything around.
- if (!visibility) {
- // Hidden, no change so drop it completely
- if (!current_frame_.visibility)
- return;
-
- frame.reset(nullptr);
- }
-
std::unique_lock<std::mutex> l(pending_frame_mutex_);
pending_frames_.emplace_back(std::move(frame), visibility);
- if (pending_frames_.size() > kMaximumPendingFrames)
+ if (pending_frames_.size() > kMaximumPendingFrames) {
+ skipped_frame_count_++;
pending_frames_.pop_front();
+ }
+
+ if (visibility == ViewMode::Hidden &&
+ current_frame_.visibility == ViewMode::Hidden) {
+ // Consume all frames while hidden.
+ while (!pending_frames_.empty())
+ AdvanceFrame();
+ }
// If we are showing ourselves the main thread is not processing anything,
// so give it a kick.
- if (visibility && !current_frame_.visibility)
+ if (visibility != ViewMode::Hidden && current_frame_.visibility == ViewMode::Hidden) {
+ QueueTask(MainThreadTask::EnteringVrMode);
QueueTask(MainThreadTask::Show);
+ }
}
bool ShellView::IsHit(const vec3& view_location, const vec3& view_direction,
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index 589902e..ba46e6d 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -14,6 +14,12 @@
namespace android {
namespace dvr {
+enum class ViewMode {
+ Hidden,
+ VR,
+ App,
+};
+
class ShellView : public Application, public HwcCallback::Client {
public:
ShellView();
@@ -57,6 +63,8 @@
bool OnClick(bool down);
+ void AdvanceFrame();
+
// HwcCallback::Client:
void OnFrame(std::unique_ptr<HwcCallback::Frame> frame) override;
@@ -64,6 +72,9 @@
std::unique_ptr<ShaderProgram> overlay_program_;
std::unique_ptr<ShaderProgram> controller_program_;
+ // This starts at -1 so we don't call ReleaseFrame for the first frame.
+ int skipped_frame_count_ = -1;
+
uint32_t current_vr_app_;
// Used to center the scene when the shell becomes visible.
@@ -92,7 +103,7 @@
struct PendingFrame {
PendingFrame() = default;
- PendingFrame(std::unique_ptr<HwcCallback::Frame>&& frame, bool visibility)
+ PendingFrame(std::unique_ptr<HwcCallback::Frame>&& frame, ViewMode visibility)
: frame(std::move(frame)), visibility(visibility) {}
PendingFrame(PendingFrame&& r)
: frame(std::move(r.frame)), visibility(r.visibility) {}
@@ -103,7 +114,7 @@
}
std::unique_ptr<HwcCallback::Frame> frame;
- bool visibility = false;
+ ViewMode visibility = ViewMode::Hidden;
};
std::deque<PendingFrame> pending_frames_;
std::mutex pending_frame_mutex_;
diff --git a/services/vr/vr_window_manager/surface_flinger_view.cpp b/services/vr/vr_window_manager/surface_flinger_view.cpp
index d38fcc0..b15d262 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.cpp
+++ b/services/vr/vr_window_manager/surface_flinger_view.cpp
@@ -38,13 +38,13 @@
bool SurfaceFlingerView::GetTextures(const HwcCallback::Frame& frame,
std::vector<TextureLayer>* texture_layers,
TextureLayer* ime_layer,
- bool debug) const {
+ bool debug, bool skip_first_layer) const {
auto& layers = frame.layers();
texture_layers->clear();
size_t start = 0;
// Skip the second layer if it is from the VR app.
- if (!debug) {
+ if (!debug && skip_first_layer) {
start = 1;
if (layers[0].appid && layers[0].appid == layers[1].appid)
start = 2;
@@ -75,5 +75,9 @@
return true;
}
+void SurfaceFlingerView::ReleaseFrame() {
+ composer_service_->releaseFrame();
+}
+
} // namespace dvr
} // namespace android
diff --git a/services/vr/vr_window_manager/surface_flinger_view.h b/services/vr/vr_window_manager/surface_flinger_view.h
index e079cdb..2e36ec1 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.h
+++ b/services/vr/vr_window_manager/surface_flinger_view.h
@@ -33,7 +33,10 @@
bool GetTextures(const HwcCallback::Frame& layers,
std::vector<TextureLayer>* texture_layers,
- TextureLayer* ime_layer, bool debug) const;
+ TextureLayer* ime_layer, bool debug,
+ bool skip_first_layer) const;
+
+ void ReleaseFrame();
private:
sp<IVrComposerView> composer_service_;
diff --git a/services/vr/vr_window_manager/vr_window_manager.cpp b/services/vr/vr_window_manager/vr_window_manager.cpp
index 736a14f..8d9ad79 100644
--- a/services/vr/vr_window_manager/vr_window_manager.cpp
+++ b/services/vr/vr_window_manager/vr_window_manager.cpp
@@ -11,11 +11,6 @@
return 1;
}
- if (app.AllocateResources()) {
- ALOGE("Failed to allocate resources");
- return 1;
- }
-
while (true)
app.DrawFrame();