Uses shared memory regions for framebuffer content and broadcast
Removes the libvsocframebuffer library and replaces its functionality
with the region views.
Bug: 70944937
Bug: 64158705
Test: run locally
Change-Id: I651ea1a676a888b399d7e9b95796147f22168afc
diff --git a/Android.bp b/Android.bp
index e66cfec..c91bc2d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -95,6 +95,8 @@
"common/vsoc/lib/e2e_test_region_view.cpp",
"common/vsoc/lib/fb_bcast_layout.cpp",
"common/vsoc/lib/fb_bcast_region_view.cpp",
+ "common/vsoc/lib/framebuffer_layout.cpp",
+ "common/vsoc/lib/framebuffer_region_view.cpp",
"common/vsoc/lib/gralloc_layout.cpp",
"common/vsoc/lib/input_events_layout.cpp",
"common/vsoc/lib/input_events_region_view.cpp",
diff --git a/common/vsoc/lib/fb_bcast_region_view.cpp b/common/vsoc/lib/fb_bcast_region_view.cpp
index 0ad526a..a50e06b 100644
--- a/common/vsoc/lib/fb_bcast_region_view.cpp
+++ b/common/vsoc/lib/fb_bcast_region_view.cpp
@@ -20,18 +20,44 @@
#include "common/vsoc/lib/lock_guard.h"
using vsoc::framebuffer::FBBroadcastRegionView;
+using vsoc::layout::framebuffer::CompositionStats;
+
+uint32_t FBBroadcastRegionView::GetAndSetNextAvailableBufferBit(
+ uint32_t filter) {
+ auto lock_guard(make_lock_guard(&data()->bcast_lock));
+ uint32_t bit = data()->buffer_bits & filter;
+ if (bit == filter) {
+ // All bits from the filter are already set.
+ return 0LU;
+ }
+ // Set available bits to 1
+ bit = (bit ^ filter);
+ // Isolate first available bit
+ bit &= ~bit + 1LU;
+ // Set it on bit set on shared memory
+ data()->buffer_bits |= bit;
+ return bit;
+}
+
+void FBBroadcastRegionView::UnsetBufferBits(uint32_t bits) {
+ auto lock_guard(make_lock_guard(&data()->bcast_lock));
+ data()->buffer_bits &= ~bits;
+}
// We can use a locking protocol because we decided that the streamer should
// have more priority than the hwcomposer, so it's OK to block the hwcomposer
// waiting for the streamer to complete, while the streamer will only block on
// the hwcomposer when it's ran out of work to do and needs to get more from the
// hwcomposer.
-void FBBroadcastRegionView::BroadcastNewFrame(uint32_t seq_num,
- vsoc_reg_off_t frame_offset) {
+void FBBroadcastRegionView::BroadcastNewFrame(vsoc_reg_off_t frame_offset,
+ const CompositionStats* stats) {
{
auto lock_guard(make_lock_guard(&data()->bcast_lock));
- data()->seq_num = seq_num;
+ data()->seq_num++;
data()->frame_offset = frame_offset;
+ if (stats) {
+ data()->stats = *stats;
+ }
}
// Signaling after releasing the lock may cause spurious wake ups.
// Signaling while holding the lock may cause the just-awaken listener to
@@ -43,7 +69,7 @@
}
vsoc_reg_off_t FBBroadcastRegionView::WaitForNewFrameSince(
- uint32_t* last_seq_num) {
+ uint32_t* last_seq_num, CompositionStats* stats) {
static std::unique_ptr<RegionWorker> worker = StartWorker();
// It's ok to read seq_num here without holding the lock because the lock will
// be acquired immediately after so we'll block if necessary to wait for the
@@ -59,6 +85,9 @@
{
auto lock_guard(make_lock_guard(&data()->bcast_lock));
*last_seq_num = data()->seq_num;
+ if (stats) {
+ *stats = data()->stats;
+ }
return data()->frame_offset;
}
}
diff --git a/common/vsoc/lib/fb_bcast_region_view.h b/common/vsoc/lib/fb_bcast_region_view.h
index e92734f..29da4b2 100644
--- a/common/vsoc/lib/fb_bcast_region_view.h
+++ b/common/vsoc/lib/fb_bcast_region_view.h
@@ -25,10 +25,20 @@
namespace vsoc {
namespace framebuffer {
+// Provides information related to the device's screen. Allows to query screen
+// properties such as resolution and dpi, as well as subscribe/notify to/of
+// changes on the screen contents. It's independent of where the buffer holding
+// the screen contents is. This region will eventually become the display
+// region, which will represent display hardware including the hardware
+// composer.
class FBBroadcastRegionView
: public vsoc::TypedRegionView<
vsoc::layout::framebuffer::FBBroadcastLayout> {
public:
+ static int align(int input, int alignment = kAlignment) {
+ return (input + alignment - 1) & -alignment;
+ }
+
// Screen width in pixels
int x_res() const { return data().x_res; }
@@ -39,10 +49,7 @@
int dpi() const { return data().dpi; }
// Refresh rate in Hertz
- int refresh_rate_hz() const {
- // TODO(jemoreira): region_->data()->refresh_rate_hz;
- return kFbRefreshRateHz;
- }
+ int refresh_rate_hz() const { return data().refresh_rate_hz; }
uint32_t pixel_format() const { return kFbPixelFormat; }
@@ -50,17 +57,38 @@
return vsoc::PixelFormatProperties<kFbPixelFormat>::bytes_per_pixel;
}
- // Broadcasts a new frame. Meant to be used exclusively by the hwcomposer.
- // Zero is an invalid frame_num, used to indicate that there is no frame
- // available. It's expected that frame_num increases monotonically over time,
- // but there is no hard requirement for this.
- // frame_offset is the offset of the current frame in the gralloc region.
- void BroadcastNewFrame(uint32_t frame_num, vsoc_reg_off_t frame_offset);
+ int line_length() const { return align(x_res() * bytes_per_pixel()); }
+
+ size_t buffer_size() const {
+ return (align(x_res() * bytes_per_pixel()) * y_res()) + kSwiftShaderPadding;
+ }
+
+ // The framebuffer broadcast region mantains a bit set to keep track of the
+ // buffers that have been allocated already. This function atomically finds an
+ // unset (0) bit in the set, sets it to 1 and returns it. The filter parameter
+ // specifies which bits to consider from the set.
+ // TODO(jemoreira): Move frame buffers to the gralloc region and remove this
+ // bitset.
+ uint32_t GetAndSetNextAvailableBufferBit(uint32_t filter);
+ void UnsetBufferBits(uint32_t bits);
+
+ // Broadcasts a new frame.
+ // frame_offset is the offset of the current frame in the framebuffer region.
+ // stats holds performance information of the last composition, can be null.
+ void BroadcastNewFrame(
+ vsoc_reg_off_t frame_offset,
+ const vsoc::layout::framebuffer::CompositionStats* stats = nullptr);
// Waits for a new frame (one with a different seq_num than last one we saw).
// Returns the offset of the new frame or zero if there was an error, stores
- // the new sequential number in *last_seq_num.
- vsoc_reg_off_t WaitForNewFrameSince(uint32_t* last_seq_num);
+ // the new sequential number in *last_seq_num. The frame sequential number are
+ // provided by the hwcomposer and expected to increase monotonically over time
+ // (though it's not a hard requirement), this numbers are guaranteed to be
+ // non-zero when a valid frame is available. Performance statistics are
+ // returned through the stats parameter when it's not null.
+ vsoc_reg_off_t WaitForNewFrameSince(
+ uint32_t* last_seq_num,
+ vsoc::layout::framebuffer::CompositionStats* stats = nullptr);
#if defined(CUTTLEFISH_HOST)
static std::shared_ptr<FBBroadcastRegionView> GetInstance(const char* domain);
@@ -68,9 +96,16 @@
static std::shared_ptr<FBBroadcastRegionView> GetInstance();
#endif
- private:
+ using Pixel = uint32_t;
+ static constexpr int kSwiftShaderPadding = 4;
+ static constexpr int kRedShift = 0;
+ static constexpr int kGreenShift = 8;
+ static constexpr int kBlueShift = 16;
+ static constexpr int kRedBits = 8;
+ static constexpr int kGreenBits = 8;
+ static constexpr int kBlueBits = 8;
static constexpr uint32_t kFbPixelFormat = vsoc::VSOC_PIXEL_FORMAT_RGBA_8888;
- static constexpr int kFbRefreshRateHz = 60;
+ static constexpr int kAlignment = 8;
};
} // namespace framebuffer
} // namespace vsoc
diff --git a/common/vsoc/lib/framebuffer_layout.cpp b/common/vsoc/lib/framebuffer_layout.cpp
new file mode 100644
index 0000000..40e9583
--- /dev/null
+++ b/common/vsoc/lib/framebuffer_layout.cpp
@@ -0,0 +1,27 @@
+/*
+ * 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 "common/vsoc/shm/framebuffer_layout.h"
+
+namespace vsoc {
+namespace layout {
+
+namespace framebuffer {
+
+const char* FrameBufferLayout::region_name = "framebuffer";
+
+} // framebuffer
+} // layout
+} // vsoc
diff --git a/common/vsoc/lib/framebuffer_region_view.cpp b/common/vsoc/lib/framebuffer_region_view.cpp
new file mode 100644
index 0000000..bc259db
--- /dev/null
+++ b/common/vsoc/lib/framebuffer_region_view.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 "common/vsoc/lib/framebuffer_region_view.h"
+
+using vsoc::framebuffer::FrameBufferRegionView;
+
+size_t FrameBufferRegionView::total_buffer_size() const {
+ return static_cast<size_t>(control_->region_data_size());
+}
+
+uint32_t FrameBufferRegionView::first_buffer_offset() const {
+ return control_->region_size() - control_->region_data_size();
+}
+
+void* FrameBufferRegionView::GetBufferFromOffset(uint32_t offset) {
+ return region_offset_to_pointer<void>(offset);
+}
diff --git a/common/vsoc/lib/framebuffer_region_view.h b/common/vsoc/lib/framebuffer_region_view.h
new file mode 100644
index 0000000..85267d2
--- /dev/null
+++ b/common/vsoc/lib/framebuffer_region_view.h
@@ -0,0 +1,59 @@
+#pragma once
+/*
+ * 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 <memory>
+
+#include "common/vsoc/lib/typed_region_view.h"
+#include "common/vsoc/shm/framebuffer_layout.h"
+
+namespace vsoc {
+namespace framebuffer {
+
+/* Grants access to the framebuffer region. It only knows about the available
+ * buffer space, but not about the distribution of that space, it's up to the
+ * gralloc hal to break it into different buffers.
+ * This region is temporary since the framebuffer should be integrated into the
+ * gralloc buffers region.*/
+class FrameBufferRegionView
+ : public vsoc::TypedRegionView<
+ vsoc::layout::framebuffer::FrameBufferLayout> {
+ public:
+
+#if defined(CUTTLEFISH_HOST)
+ static std::shared_ptr<FrameBufferRegionView> GetInstance(
+ const char* domain) {
+ return RegionView::GetInstanceImpl<FrameBufferRegionView>(
+ [](std::shared_ptr<FrameBufferRegionView> region, const char* domain) {
+ return region->Open(domain);
+ },
+ domain);
+ }
+#else
+ static std::shared_ptr<FrameBufferRegionView> GetInstance() {
+ return RegionView::GetInstanceImpl<FrameBufferRegionView>(
+ std::mem_fn(&FrameBufferRegionView::Open));
+ }
+#endif
+
+ size_t total_buffer_size() const;
+ uint32_t first_buffer_offset() const;
+ // Gets a pointer to an offset of the region.
+ void* GetBufferFromOffset(uint32_t offset);
+};
+
+} // namespace framebuffer
+} // namespace vsoc
diff --git a/common/vsoc/lib/region_control.h b/common/vsoc/lib/region_control.h
index 82464aa..fd9377e 100644
--- a/common/vsoc/lib/region_control.h
+++ b/common/vsoc/lib/region_control.h
@@ -16,6 +16,7 @@
* limitations under the License.
*/
+#include <sys/mman.h>
#include <stdint.h>
#include <memory>
#include "uapi/vsoc_shm.h"
diff --git a/common/vsoc/shm/fb_bcast_layout.h b/common/vsoc/shm/fb_bcast_layout.h
index 21985c0..711e600 100644
--- a/common/vsoc/shm/fb_bcast_layout.h
+++ b/common/vsoc/shm/fb_bcast_layout.h
@@ -25,6 +25,23 @@
namespace layout {
namespace framebuffer {
+struct TimeSpec {
+ int64_t ts_sec;
+ uint32_t ts_nsec;
+ // Host and guest compilers are giving the structure different sizes without
+ // this field.
+ uint32_t reserved;
+};
+struct CompositionStats {
+ uint32_t num_prepare_calls;
+ uint16_t num_layers;
+ uint16_t num_hwcomposited_layers;
+ TimeSpec last_vsync;
+ TimeSpec prepare_start;
+ TimeSpec prepare_end;
+ TimeSpec set_start;
+ TimeSpec set_end;
+};
struct FBBroadcastLayout : public RegionLayout {
static const char* region_name;
@@ -34,15 +51,19 @@
uint16_t dpi;
uint16_t refresh_rate_hz;
+ uint32_t buffer_bits;
+
// The frame sequential number
std::atomic<uint32_t> seq_num;
// The offset in the gralloc buffer region of the current frame buffer.
uint32_t frame_offset;
- // Protects access to the frame offset and sequential number.
+ CompositionStats stats;
+ // Protects access to the frame offset, sequential number and stats.
// See the region implementation for more details.
SpinLock bcast_lock;
+ uint32_t reserved;
};
-ASSERT_SHM_COMPATIBLE(FBBroadcastLayout, framebuffer);
+ASSERT_SHM_COMPATIBLE(FBBroadcastLayout, fb_broadcast);
} // namespace framebuffer
diff --git a/common/vsoc/shm/framebuffer_layout.h b/common/vsoc/shm/framebuffer_layout.h
new file mode 100644
index 0000000..a7af31e
--- /dev/null
+++ b/common/vsoc/shm/framebuffer_layout.h
@@ -0,0 +1,36 @@
+#pragma once
+/*
+ * 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 "common/vsoc/shm/base.h"
+#include "common/vsoc/shm/version.h"
+
+// Memory for the framebuffer region
+
+namespace vsoc {
+namespace layout {
+
+namespace framebuffer {
+
+struct FrameBufferLayout : public RegionLayout {
+ static const char* region_name;
+};
+ASSERT_SHM_COMPATIBLE(FrameBufferLayout, framebuffer);
+
+} // namespace framebuffer
+
+} // namespace layout
+} // namespace vsoc
diff --git a/common/vsoc/shm/version.h b/common/vsoc/shm/version.h
index 7a4e329..459fdb2 100644
--- a/common/vsoc/shm/version.h
+++ b/common/vsoc/shm/version.h
@@ -116,11 +116,20 @@
// Versioning information for fb_bcast_layout.h
// Changes to these structures will affect only the framebuffer broadcast region
+namespace fb_broadcast {
+namespace {
+const uint32_t version = 2;
+}
+static const std::size_t FBBroadcastLayout_size = 120;
+} // namespace fb_broadcast
+
+// Versioning information for framebuffer_layout.h
+// Changes to these structures will affect only the framebuffer broadcast region
namespace framebuffer {
namespace {
const uint32_t version = 1;
}
-static const std::size_t FBBroadcastLayout_size = 24;
+static const std::size_t FrameBufferLayout_size = 1;
} // namespace framebuffer
// Versioning information for wifi_layout.h
diff --git a/guest/frontend/vnc_server/Android.mk b/guest/frontend/vnc_server/Android.mk
index e0a4e0d..4b008f3 100644
--- a/guest/frontend/vnc_server/Android.mk
+++ b/guest/frontend/vnc_server/Android.mk
@@ -60,8 +60,7 @@
cuttlefish_auto_resources \
cuttlefish_tcp_socket \
libcuttlefish_fs \
- vsoc_lib \
- libvsocframebuffer
+ vsoc_lib
LOCAL_STATIC_LIBRARIES := \
libjsoncpp
diff --git a/guest/frontend/vnc_server/simulated_hw_composer.cpp b/guest/frontend/vnc_server/simulated_hw_composer.cpp
index 473a6f9..f0e43bd 100644
--- a/guest/frontend/vnc_server/simulated_hw_composer.cpp
+++ b/guest/frontend/vnc_server/simulated_hw_composer.cpp
@@ -16,27 +16,25 @@
#include "simulated_hw_composer.h"
+#include "common/vsoc/lib/framebuffer_region_view.h"
+
using cvd::vnc::SimulatedHWComposer;
+using vsoc::framebuffer::FrameBufferRegionView;
+using vsoc::framebuffer::FBBroadcastRegionView;
SimulatedHWComposer::SimulatedHWComposer(BlackBoard* bb)
:
#ifdef FUZZ_TEST_VNC
engine_{std::random_device{}()},
#endif
- control_{VSoCFrameBufferControl::getInstance()},
bb_{bb},
stripes_(kMaxQueueElements, &SimulatedHWComposer::EraseHalfOfElements) {
- void* p{};
- VSoCFrameBuffer::OpenAndMapFrameBuffer(&p, &frame_buffer_fd_);
- frame_buffer_memory_ = static_cast<char*>(p);
stripe_maker_ = std::thread(&SimulatedHWComposer::MakeStripes, this);
}
SimulatedHWComposer::~SimulatedHWComposer() {
close();
stripe_maker_.join();
- VSoCFrameBuffer::UnmapAndCloseFrameBuffer(frame_buffer_memory_,
- frame_buffer_fd_);
}
cvd::vnc::Stripe SimulatedHWComposer::GetNewStripe() {
@@ -77,12 +75,11 @@
std::uint64_t stripe_seq_num = 1;
while (!closed()) {
bb_->WaitForAtLeastOneClientConnection();
- int y_offset{};
- control_.WaitForFrameBufferChangeSince(previous_seq_num, &y_offset,
- &previous_seq_num, nullptr);
-
- const auto* frame_start =
- frame_buffer_memory_ + y_offset * ActualScreenWidth() * BytesPerPixel();
+ uint32_t offset =
+ FBBroadcastRegionView::GetInstance()->WaitForNewFrameSince(
+ &previous_seq_num);
+ const char* frame_start = static_cast<char*>(
+ FrameBufferRegionView::GetInstance()->GetBufferFromOffset(offset));
raw_screen.assign(frame_start, frame_start + ScreenSizeInBytes());
for (int i = 0; i < kNumStripes; ++i) {
diff --git a/guest/frontend/vnc_server/simulated_hw_composer.h b/guest/frontend/vnc_server/simulated_hw_composer.h
index c8a8320..79eeafd 100644
--- a/guest/frontend/vnc_server/simulated_hw_composer.h
+++ b/guest/frontend/vnc_server/simulated_hw_composer.h
@@ -15,12 +15,6 @@
* limitations under the License.
*/
-#include "blackboard.h"
-
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h>
-#include <common/libs/thread_safe_queue/thread_safe_queue.h>
-
#include <mutex>
#include <thread>
@@ -29,6 +23,11 @@
#include <random>
#endif
+#include "common/libs/thread_safe_queue/thread_safe_queue.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+
+#include "blackboard.h"
+
namespace cvd {
namespace vnc {
class SimulatedHWComposer {
@@ -58,12 +57,9 @@
constexpr static std::size_t kMaxQueueElements = 64;
bool closed_ GUARDED_BY(m_){};
std::mutex m_;
- VSoCFrameBufferControl& control_;
BlackBoard* bb_{};
ThreadSafeQueue<Stripe> stripes_;
std::thread stripe_maker_;
- char* frame_buffer_memory_{};
- int frame_buffer_fd_{};
};
} // namespace vnc
} // namespace cvd
diff --git a/guest/frontend/vnc_server/vnc_client_connection.cpp b/guest/frontend/vnc_server/vnc_client_connection.cpp
index 957e7e7..b3f272e 100644
--- a/guest/frontend/vnc_server/vnc_client_connection.cpp
+++ b/guest/frontend/vnc_server/vnc_client_connection.cpp
@@ -20,8 +20,6 @@
#include "common/libs/tcp_socket/tcp_socket.h"
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer.h>
-
#include <netinet/in.h>
#include <sys/time.h>
@@ -47,6 +45,7 @@
using cvd::vnc::Stripe;
using cvd::vnc::StripePtrVec;
using cvd::vnc::VncClientConnection;
+using vsoc::framebuffer::FBBroadcastRegionView;
namespace {
class BigEndianChecker {
@@ -140,18 +139,18 @@
}
std::uint32_t RedVal(std::uint32_t pixel) {
- return (pixel >> VSoCFrameBuffer::kRedShift) &
- ((0x1 << VSoCFrameBuffer::kRedBits) - 1);
+ return (pixel >> FBBroadcastRegionView::kRedShift) &
+ ((0x1 << FBBroadcastRegionView::kRedBits) - 1);
}
std::uint32_t BlueVal(std::uint32_t pixel) {
- return (pixel >> VSoCFrameBuffer::kBlueShift) &
- ((0x1 << VSoCFrameBuffer::kBlueBits) - 1);
+ return (pixel >> FBBroadcastRegionView::kBlueShift) &
+ ((0x1 << FBBroadcastRegionView::kBlueBits) - 1);
}
std::uint32_t GreenVal(std::uint32_t pixel) {
- return (pixel >> VSoCFrameBuffer::kGreenShift) &
- ((0x1 << VSoCFrameBuffer::kGreenBits) - 1);
+ return (pixel >> FBBroadcastRegionView::kGreenShift) &
+ ((0x1 << FBBroadcastRegionView::kGreenBits) - 1);
}
} // namespace
namespace cvd {
@@ -304,7 +303,7 @@
void VncClientConnection::AppendRawStripe(Message* frame_buffer_update,
const Stripe& stripe) const {
- using Pixel = VSoCFrameBuffer::Pixel;
+ using Pixel = FBBroadcastRegionView::Pixel;
auto& fbu = *frame_buffer_update;
AppendRawStripeHeader(&fbu, stripe);
auto init_size = fbu.size();
diff --git a/guest/frontend/vnc_server/vnc_utils.h b/guest/frontend/vnc_server/vnc_utils.h
index 3a23d45..e25f860 100644
--- a/guest/frontend/vnc_server/vnc_utils.h
+++ b/guest/frontend/vnc_server/vnc_utils.h
@@ -15,14 +15,13 @@
* limitations under the License.
*/
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer.h>
-
#include <vector>
#include <array>
#include <utility>
#include <cstdint>
#include "common/libs/tcp_socket/tcp_socket.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
#undef D
#ifdef VSOC_VNC_DEBUG
@@ -73,17 +72,17 @@
};
inline constexpr int BytesPerPixel() {
- return sizeof(VSoCFrameBuffer::Pixel);
+ return sizeof(vsoc::framebuffer::FBBroadcastRegionView::Pixel);
}
// The width of the screen regardless of orientation. Does not change.
inline int ActualScreenWidth() {
- return VSoCFrameBuffer::getInstance().x_res();
+ return vsoc::framebuffer::FBBroadcastRegionView::GetInstance()->x_res();
}
// The height of the screen regardless of orientation. Does not change.
inline int ActualScreenHeight() {
- return VSoCFrameBuffer::getInstance().y_res();
+ return vsoc::framebuffer::FBBroadcastRegionView::GetInstance()->y_res();
}
inline int ScreenSizeInBytes() {
diff --git a/guest/hals/gralloc/legacy/Android.mk b/guest/hals/gralloc/legacy/Android.mk
index 030ca35..fe01635 100644
--- a/guest/hals/gralloc/legacy/Android.mk
+++ b/guest/hals/gralloc/legacy/Android.mk
@@ -19,7 +19,8 @@
VSOC_GRALLOC_COMMON_SRC_FILES := \
gralloc.cpp \
framebuffer.cpp \
- mapper.cpp
+ mapper.cpp \
+ region_registry.cpp
VSOC_GRALLOC_COMMON_CFLAGS:= \
-DLOG_TAG=\"gralloc_vsoc_legacy\" \
@@ -35,16 +36,19 @@
LOCAL_SRC_FILES := $(VSOC_GRALLOC_COMMON_SRC_FILES)
LOCAL_CFLAGS := $(VSOC_GRALLOC_COMMON_CFLAGS)
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
+LOCAL_C_INCLUDES := \
+ device/google/cuttlefish_common \
+ device/google/cuttlefish_kernel
LOCAL_HEADER_LIBRARIES := \
libhardware_headers
LOCAL_SHARED_LIBRARIES := \
+ libbase \
liblog \
libutils \
libcutils \
- libvsocframebuffer
+ vsoc_lib
LOCAL_VENDOR_MODULE := true
diff --git a/guest/hals/gralloc/legacy/framebuffer.cpp b/guest/hals/gralloc/legacy/framebuffer.cpp
index 4251433..8b0f4df 100644
--- a/guest/hals/gralloc/legacy/framebuffer.cpp
+++ b/guest/hals/gralloc/legacy/framebuffer.cpp
@@ -40,12 +40,16 @@
#endif
#include "gralloc_vsoc_priv.h"
+#include "region_registry.h"
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h>
-#include <guest/libs/legacy_framebuffer/RegionRegistry.h>
#include "common/libs/auto_resources/auto_resources.h"
#include "common/libs/threads/cuttlefish_thread.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+#include "common/vsoc/lib/framebuffer_region_view.h"
+#include "common/vsoc/shm/framebuffer_layout.h"
+
+using vsoc::framebuffer::FBBroadcastRegionView;
+using vsoc::framebuffer::FrameBufferRegionView;
/*****************************************************************************/
@@ -77,17 +81,14 @@
return 0;
}
-static int fb_post(struct framebuffer_device_t* dev __unused, buffer_handle_t buffer) {
- const int yoffset = YOffsetFromHandle(buffer);
- if (yoffset >= 0) {
- int retval =
- VSoCFrameBufferControl::getInstance().BroadcastFrameBufferChanged(
- yoffset);
- if (retval) ALOGI("Failed to post framebuffer");
-
- return retval;
+static int fb_post(struct framebuffer_device_t* dev __unused,
+ buffer_handle_t buffer) {
+ const int offset = OffsetFromHandle(buffer);
+ if (offset < 0 ) {
+ return offset;
}
- return -1;
+ FBBroadcastRegionView::GetInstance()->BroadcastNewFrame(offset);
+ return 0;
}
/*****************************************************************************/
@@ -98,24 +99,28 @@
return 0;
}
+ // TODO(jemoreira): This assumes the location of the region device nodes, it
+ // should get the path from a more centralized place and have the guest region
+ // control use that as well.
+ std::string fb_file_path = std::string("/dev/").append(
+ vsoc::layout::framebuffer::FrameBufferLayout::region_name);
int fd;
- if (!VSoCFrameBuffer::OpenFrameBuffer(&fd)) {
+ if ((fd = open(fb_file_path.c_str(), O_RDWR)) < 0) {
+ ALOGE("Failed to open '%s' (%s)", fb_file_path.c_str(), strerror(errno));
return -errno;
}
- const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
+ auto framebuffer = FrameBufferRegionView::GetInstance();
/*
- * map the framebuffer
+ * MAP the framebuffer
*/
- module->framebuffer =
- new private_handle_t(fd,
- config.total_buffer_size(),
- config.hal_format(),
- config.x_res(),
- config.y_res(),
- config.line_length() / (config.bits_per_pixel() / 8),
- private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
+ module->framebuffer = new private_handle_t(
+ fd, framebuffer->total_buffer_size(), HAL_PIXEL_FORMAT_RGBX_8888,
+ fb_broadcast->x_res(), fb_broadcast->y_res(),
+ fb_broadcast->line_length() / fb_broadcast->bytes_per_pixel(),
+ private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
reference_region("framebuffer_init", module->framebuffer);
return 0;
@@ -154,20 +159,21 @@
status = initUserspaceFrameBuffer(m);
- const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
if (status >= 0) {
- int stride = config.line_length() / (config.bits_per_pixel() / 8);
- int format = config.hal_format();
+ int stride =
+ fb_broadcast->line_length() / fb_broadcast->bytes_per_pixel();
+ int format = HAL_PIXEL_FORMAT_RGBX_8888;
const_cast<uint32_t&>(dev->device.flags) = 0;
- const_cast<uint32_t&>(dev->device.width) = config.x_res();
- const_cast<uint32_t&>(dev->device.height) = config.y_res();
+ const_cast<uint32_t&>(dev->device.width) = fb_broadcast->x_res();
+ const_cast<uint32_t&>(dev->device.height) = fb_broadcast->y_res();
const_cast<int&>(dev->device.stride) = stride;
const_cast<int&>(dev->device.format) = format;
- const_cast<float&>(dev->device.xdpi) = config.dpi();
- const_cast<float&>(dev->device.ydpi) = config.dpi();
- // TODO (jemoreira): DRY!! Managed by the vsync thread in the hwcomposer
- const_cast<float&>(dev->device.fps) = (60 * 1000) / 1000.0f;
+ const_cast<float&>(dev->device.xdpi) = fb_broadcast->dpi();
+ const_cast<float&>(dev->device.ydpi) = fb_broadcast->dpi();
+ const_cast<float&>(dev->device.fps) =
+ (fb_broadcast->refresh_rate_hz() * 1000) / 1000.0f;
const_cast<int&>(dev->device.minSwapInterval) = 1;
const_cast<int&>(dev->device.maxSwapInterval) = 1;
*device = &dev->device.common;
diff --git a/guest/hals/gralloc/legacy/gralloc.cpp b/guest/hals/gralloc/legacy/gralloc.cpp
index e2c4104..f90fd4f 100644
--- a/guest/hals/gralloc/legacy/gralloc.cpp
+++ b/guest/hals/gralloc/legacy/gralloc.cpp
@@ -36,14 +36,21 @@
#include <guest/libs/platform_support/api_level_fixes.h>
-#include "guest/libs/legacy_framebuffer/vsoc_framebuffer.h"
-#include "guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h"
-#include "guest/libs/legacy_framebuffer/RegionRegistry.h"
-#include "gralloc_vsoc_priv.h"
#include "common/libs/auto_resources/auto_resources.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+#include "common/vsoc/lib/framebuffer_region_view.h"
+#include "gralloc_vsoc_priv.h"
+#include "region_registry.h"
+
+using vsoc::framebuffer::FBBroadcastRegionView;
+using vsoc::framebuffer::FrameBufferRegionView;
/*****************************************************************************/
+static inline size_t roundUpToPageSize(size_t x) {
+ return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+}
+
static int gralloc_alloc_buffer(
alloc_device_t* /*dev*/, int format, int w, int h,
buffer_handle_t* pHandle, int* pStrideInPixels) {
@@ -59,9 +66,9 @@
// a gralloc buffer in this format.
ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888);
if (format == HAL_PIXEL_FORMAT_YV12) {
- bytes_per_line = VSoCFrameBuffer::align(bytes_per_pixel * w, 16);
+ bytes_per_line = FBBroadcastRegionView::align(bytes_per_pixel * w, 16);
} else {
- bytes_per_line = VSoCFrameBuffer::align(bytes_per_pixel * w);
+ bytes_per_line = FBBroadcastRegionView::align(bytes_per_pixel * w);
}
size = roundUpToPageSize(size + formatToBytesPerFrame(format, w, h));
size += PAGE_SIZE;
@@ -108,14 +115,14 @@
}
static int gralloc_free_framebuffer(private_handle_t const * hnd) {
- static const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
- static VSoCFrameBufferControl& fb_control =
- VSoCFrameBufferControl::getInstance();
-
- // free this buffer
- const size_t bufferSize = config.line_length() * config.y_res();
- int index = hnd->frame_offset / bufferSize;
- return fb_control.UnsetBufferBits(1LU << index);
+ // free this buffer
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
+ auto framebuffer = FrameBufferRegionView::GetInstance();
+ const size_t bufferSize = fb_broadcast->buffer_size();
+ int index =
+ (hnd->frame_offset - framebuffer->first_buffer_offset()) / bufferSize;
+ fb_broadcast->UnsetBufferBits(1LU << index);
+ return 0;
}
// Allocates a framebuffer taken from the set of buffers given by buffer_mask.
@@ -123,40 +130,39 @@
buffer_handle_t* pHandle,
int* pStrideInPixels,
uint32_t buffer_mask) {
- static const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
- static VSoCFrameBufferControl& fb_control =
- VSoCFrameBufferControl::getInstance();
-
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
ensure_framebuffer_allocated(m);
- const uint32_t numBuffers = VSoCFrameBuffer::kNumBuffers;
- const size_t bufferSize = config.bufferSize();
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
+ auto framebuffer = FrameBufferRegionView::GetInstance();
+ const size_t buffer_size = fb_broadcast->buffer_size();
+ const uint32_t numBuffers = framebuffer->total_buffer_size() / buffer_size;
// Paranoia: Force the mask to be valid
buffer_mask &= (1LU << numBuffers) - 1;
- uint32_t bit = fb_control.GetAndSetNextAvailableBufferBit(buffer_mask);
+ uint32_t bit = fb_broadcast->GetAndSetNextAvailableBufferBit(buffer_mask);
if (!bit) {
// All buffers in the mask have been allocated already or there was another
// error
return -ENOMEM;
}
- int frame_offset = 0;
+ int frame_offset = framebuffer->first_buffer_offset();
while (bit != 1LU) {
bit >>= 1;
- frame_offset += bufferSize;
+ frame_offset += buffer_size;
}
- int stride_in_pixels = config.line_length() / (config.bits_per_pixel() / 8);
+ int stride_in_pixels =
+ fb_broadcast->line_length() / fb_broadcast->bytes_per_pixel();
// create a "fake" handle for it
private_handle_t* hnd = new private_handle_t(
- dup(m->framebuffer->fd), config.total_buffer_size(),
- config.hal_format(), config.x_res(), config.y_res(),
+ dup(m->framebuffer->fd), framebuffer->total_buffer_size(),
+ HAL_PIXEL_FORMAT_RGBX_8888, fb_broadcast->x_res(), fb_broadcast->y_res(),
stride_in_pixels, private_handle_t::PRIV_FLAGS_FRAMEBUFFER, frame_offset);
*pHandle = hnd;
@@ -170,16 +176,28 @@
static int gralloc_alloc_sf_framebuffer(alloc_device_t* dev,
buffer_handle_t* pHandle,
int* pStrideInPixels) {
- uint32_t mask = (1LU << VSoCFrameBuffer::kNumSfBuffers) - 1LU;
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
+ auto framebuffer = FrameBufferRegionView::GetInstance();
+ int buffer_count =
+ framebuffer->total_buffer_size() / fb_broadcast->buffer_size();
+ int hwc_buffer_count = buffer_count / 2;
+ // This is not buffer_count / 2 if the number of buffer is odd.
+ int sf_buffer_count = buffer_count - hwc_buffer_count;
+ uint32_t mask = (1LU << (sf_buffer_count)) - 1LU;
// Skip the first buffers since those are for HWC usage
- mask <<= VSoCFrameBuffer::kNumHwcBuffers;
+ mask <<= hwc_buffer_count;
return gralloc_alloc_framebuffer(dev, pHandle, pStrideInPixels, mask);
}
static int gralloc_alloc_hwc_framebuffer(alloc_device_t* dev,
buffer_handle_t* pHandle) {
- // Use the first kNumHwcBuffers for hwcomposer
- uint32_t mask = (1LU << VSoCFrameBuffer::kNumHwcBuffers) - 1LU;
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
+ auto framebuffer = FrameBufferRegionView::GetInstance();
+ int buffer_count =
+ framebuffer->total_buffer_size() / fb_broadcast->buffer_size();
+ // Use the first buffers for hwcomposer
+ int hwc_buffer_count = buffer_count / 2;
+ uint32_t mask = (1LU << hwc_buffer_count) - 1LU;
return gralloc_alloc_framebuffer(dev, pHandle, NULL, mask);
}
diff --git a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
index 579ec79..67ed0ad 100644
--- a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
+++ b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
@@ -28,7 +28,7 @@
#include <linux/fb.h>
-#include "guest/libs/legacy_framebuffer/vsoc_framebuffer.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
#include "guest/libs/platform_support/api_level_fixes.h"
#ifndef GRALLOC_MODULE_API_VERSION_0_2
@@ -157,6 +157,93 @@
}
}
+inline const char* pixel_format_to_string(int format) {
+ switch (format) {
+ // Formats that are universal across versions
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return "RGBA_8888";
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return "RGBX_8888";
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return "BGRA_8888";
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return "RGB_888";
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return "RGB_565";
+ case HAL_PIXEL_FORMAT_YV12:
+ return "YV12";
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ return "YCrCb_420_SP";
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ return "YCbCr_422_SP";
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ return "YCbCr_422_I";
+
+#if VSOC_PLATFORM_SDK_AFTER(J)
+ // First supported on JBMR1 (API 17)
+ case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+ return "IMPLEMENTATION_DEFINED";
+ case HAL_PIXEL_FORMAT_BLOB:
+ return "BLOB";
+#endif
+#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
+ // First supported on JBMR2 (API 18)
+ case HAL_PIXEL_FORMAT_YCbCr_420_888:
+ return "YCbCr_420_888";
+ case HAL_PIXEL_FORMAT_Y8:
+ return "Y8";
+ case HAL_PIXEL_FORMAT_Y16:
+ return "Y16";
+#endif
+#if VSOC_PLATFORM_SDK_AFTER(K)
+ // Support was added in L (API 21)
+ case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+ return "RAW_OPAQUE";
+ // This is an alias for RAW_SENSOR in L and replaces it in M.
+ case HAL_PIXEL_FORMAT_RAW16:
+ return "RAW16";
+ case HAL_PIXEL_FORMAT_RAW10:
+ return "RAW10";
+#endif
+#if VSOC_PLATFORM_SDK_AFTER(L_MR1)
+ case HAL_PIXEL_FORMAT_YCbCr_444_888:
+ return "YCbCr_444_888";
+ case HAL_PIXEL_FORMAT_YCbCr_422_888:
+ return "YCbCr_422_888";
+ case HAL_PIXEL_FORMAT_RAW12:
+ return "RAW12";
+ case HAL_PIXEL_FORMAT_FLEX_RGBA_8888:
+ return "FLEX_RGBA_8888";
+ case HAL_PIXEL_FORMAT_FLEX_RGB_888:
+ return "FLEX_RGB_888";
+#endif
+
+ // Formats that have been removed
+#if VSOC_PLATFORM_SDK_BEFORE(K)
+ // Support was dropped on K (API 19)
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ return "RGBA_5551";
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ return "RGBA_4444";
+#endif
+#if VSOC_PLATFORM_SDK_BEFORE(L)
+ // Renamed to RAW_16 in L. Both were present for L, but it was completely
+ // removed in M.
+ case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ return "RAW_SENSOR";
+#endif
+#if VSOC_PLATFORM_SDK_AFTER(J_MR2) && VSOC_PLATFORM_SDK_BEFORE(M)
+ // Supported K, L, and LMR1. Not supported on JBMR0, JBMR1, JBMR2, and M
+ case HAL_PIXEL_FORMAT_sRGB_X_8888:
+ return "sRGB_X_8888";
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ return "sRGB_A_8888";
+#endif
+ }
+ return "UNKNOWN";
+}
+
+
static inline void formatToYcbcr(
int format, int width, int height, void* base_v, android_ycbcr* out) {
char* it = static_cast<char*>(base_v);
@@ -167,8 +254,9 @@
#ifdef GRALLOC_MODULE_API_VERSION_0_2
case HAL_PIXEL_FORMAT_YCbCr_420_888:
#endif
- out->ystride = VSoCFrameBuffer::align(width, 16);
- out->cstride = VSoCFrameBuffer::align(out->ystride / 2, 16);
+ out->ystride = vsoc::framebuffer::FBBroadcastRegionView::align(width, 16);
+ out->cstride =
+ vsoc::framebuffer::FBBroadcastRegionView::align(out->ystride / 2, 16);
out->chroma_step = 1;
out->y = it;
it += out->ystride * height;
@@ -204,23 +292,25 @@
formatToYcbcr(format, w, h, NULL, &strides);
y_size = strides.ystride * h;
c_size = strides.cstride * h / 2;
- return (y_size + 2 * c_size + VSoCFrameBuffer::kSwiftShaderPadding);
+ return (y_size + 2 * c_size +
+ vsoc::framebuffer::FBBroadcastRegionView::kSwiftShaderPadding);
/*case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:*/
default:
- w16 = VSoCFrameBuffer::align(w, 16);
- h16 = VSoCFrameBuffer::align(h, 16);
- return bytes_per_pixel * w16 * h16 + VSoCFrameBuffer::kSwiftShaderPadding;
+ w16 = vsoc::framebuffer::FBBroadcastRegionView::align(w, 16);
+ h16 = vsoc::framebuffer::FBBroadcastRegionView::align(h, 16);
+ return bytes_per_pixel * w16 * h16 +
+ vsoc::framebuffer::FBBroadcastRegionView::kSwiftShaderPadding;
}
}
-// Calculates the yoffset from a framebuffer handle. I checks the given handle
-// for errors first. Returns the yoffset (non negative integer) or -1 if there
+// Calculates the offset from a framebuffer handle. It checks the given handle
+// for errors first. Returns the offset (non negative integer) or -1 if there
// is an error.
-static inline int YOffsetFromHandle(buffer_handle_t buffer_hnd) {
+static inline int OffsetFromHandle(buffer_handle_t buffer_hnd) {
if (!buffer_hnd) {
ALOGE("Attempt to post null buffer");
return -1;
@@ -236,8 +326,7 @@
return -1;
}
- const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
- return hnd->frame_offset / config.line_length();
+ return hnd->frame_offset;
}
int fb_device_open(
diff --git a/guest/hals/gralloc/legacy/mapper.cpp b/guest/hals/gralloc/legacy/mapper.cpp
index 8339df9..17effa9 100644
--- a/guest/hals/gralloc/legacy/mapper.cpp
+++ b/guest/hals/gralloc/legacy/mapper.cpp
@@ -31,10 +31,8 @@
#include <hardware/gralloc.h>
#include <system/graphics.h>
-#include "guest/libs/legacy_framebuffer/RegionRegistry.h"
-
#include "gralloc_vsoc_priv.h"
-#include "guest/libs/remoter/remoter_framework_pkt.h"
+#include "region_registry.h"
#define DEBUG_REFERENCES 1
#define DEBUG_MAX_LOCK_LEVEL 20
diff --git a/guest/libs/legacy_framebuffer/RegionRegistry.cpp b/guest/hals/gralloc/legacy/region_registry.cpp
similarity index 98%
rename from guest/libs/legacy_framebuffer/RegionRegistry.cpp
rename to guest/hals/gralloc/legacy/region_registry.cpp
index 24010b0..5207fff 100644
--- a/guest/libs/legacy_framebuffer/RegionRegistry.cpp
+++ b/guest/hals/gralloc/legacy/region_registry.cpp
@@ -13,6 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "VSoCGrallocRegionRegistry"
+
#include <limits.h>
#include <errno.h>
#include <pthread.h>
@@ -24,7 +30,6 @@
#include <sys/types.h>
#include <cutils/hashmap.h>
-#define LOG_TAG "VSoCGrallocRegionRegistry"
#include <cutils/log.h>
#include <cutils/atomic.h>
@@ -34,7 +39,7 @@
#include <hardware/gralloc.h>
#include <system/graphics.h>
-#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
+#include "gralloc_vsoc_priv.h"
// TODO(ghartman): Make the configurable through a property
static const bool g_log_refs = false;
diff --git a/guest/libs/legacy_framebuffer/RegionRegistry.h b/guest/hals/gralloc/legacy/region_registry.h
similarity index 100%
rename from guest/libs/legacy_framebuffer/RegionRegistry.h
rename to guest/hals/gralloc/legacy/region_registry.h
diff --git a/guest/hals/hwcomposer/hwcomposer.cpp b/guest/hals/hwcomposer/hwcomposer.cpp
index cb59136..0e3374e 100644
--- a/guest/hals/hwcomposer/hwcomposer.cpp
+++ b/guest/hals/hwcomposer/hwcomposer.cpp
@@ -162,12 +162,11 @@
ALOGW("Skipping layer %zu due to failed sanity check", i);
continue;
}
- vsoc_hwc_device* pdev = reinterpret_cast<vsoc_hwc_device*>(dev);
const vsoc_buffer_handle_t* fb_handle =
reinterpret_cast<const vsoc_buffer_handle_t*>(
list->hwLayers[i].handle);
FBBroadcastRegionView::GetInstance()->BroadcastNewFrame(
- pdev->frame_num++, fb_handle->offset);
+ fb_handle->offset);
break;
}
}
diff --git a/guest/hals/hwcomposer/legacy/Android.mk b/guest/hals/hwcomposer/legacy/Android.mk
index 672d139..23faeee 100644
--- a/guest/hals/hwcomposer/legacy/Android.mk
+++ b/guest/hals/hwcomposer/legacy/Android.mk
@@ -51,7 +51,6 @@
LOCAL_VENDOR_MODULE := true
LOCAL_SHARED_LIBRARIES := \
- libvsocframebuffer \
liblog \
libbase \
libcutils \
@@ -59,6 +58,7 @@
libsync \
libhardware \
libjpeg \
+ vsoc_lib \
$(VSOC_STLPORT_LIBS)
LOCAL_STATIC_LIBRARIES := \
@@ -77,6 +77,7 @@
LOCAL_C_INCLUDES := \
device/google/cuttlefish_common \
+ device/google/cuttlefish_kernel \
bionic \
$(VSOC_STLPORT_INCLUDES)
diff --git a/guest/hals/hwcomposer/legacy/base_composer.cpp b/guest/hals/hwcomposer/legacy/base_composer.cpp
index f41ed3b..ed50cf4 100644
--- a/guest/hals/hwcomposer/legacy/base_composer.cpp
+++ b/guest/hals/hwcomposer/legacy/base_composer.cpp
@@ -17,16 +17,19 @@
#include "base_composer.h"
#include <cutils/log.h>
-#include "guest/hals/gralloc//legacy/gralloc_vsoc_priv.h"
-#include "guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h"
+
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
+
+using vsoc::framebuffer::FBBroadcastRegionView;
namespace cvd {
namespace {
-int BroadcastFrameBufferChanged(int yoffset) {
- return VSoCFrameBufferControl::getInstance().BroadcastFrameBufferChanged(
- yoffset);
+void BroadcastFrameBufferChanged(int32_t offset) {
+ FBBroadcastRegionView::GetInstance()->BroadcastNewFrame(
+ static_cast<uint32_t>(offset));
}
} // namespace
@@ -51,18 +54,13 @@
void BaseComposer::Dump(char* buff __unused, int buff_len __unused) {}
-int BaseComposer::PostFrameBuffer(buffer_handle_t buffer) {
- const int yoffset = YOffsetFromHandle(buffer);
- // If the broadcaster is NULL or could not get a good yoffset just ignore it.
- if (fb_broadcaster_ && yoffset >= 0) {
- int retval = fb_broadcaster_(yoffset);
- if (retval) {
- ALOGI("Failed to post framebuffer");
- return -1;
- }
+int32_t BaseComposer::PostFrameBuffer(buffer_handle_t buffer) {
+ const int32_t offset = OffsetFromHandle(buffer);
+ // If the broadcaster is NULL or could not get a good offset just ignore it.
+ if (fb_broadcaster_ && offset >= 0) {
+ fb_broadcaster_(offset);
}
-
- return yoffset;
+ return offset;
}
int BaseComposer::PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) {
@@ -76,7 +74,7 @@
return 0;
}
-int BaseComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+int32_t BaseComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
for (size_t idx = 0; idx < num_layers; idx++) {
if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
return PostFrameBuffer(layers[idx].handle);
diff --git a/guest/hals/hwcomposer/legacy/base_composer.h b/guest/hals/hwcomposer/legacy/base_composer.h
index fd9db9d..3577da3 100644
--- a/guest/hals/hwcomposer/legacy/base_composer.h
+++ b/guest/hals/hwcomposer/legacy/base_composer.h
@@ -20,7 +20,7 @@
namespace cvd {
-typedef int (*FbBroadcaster)(int);
+using FbBroadcaster = void (*)(int);
class BaseComposer {
public:
@@ -30,13 +30,13 @@
// Sets the composition type of each layer and returns the number of layers
// to be composited by the hwcomposer.
int PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers);
- // Returns the yoffset that was broadcasted or a negative number if there was
+ // Returns the offset that was broadcasted or a negative number if there was
// an error.
- int SetLayers(size_t num_layers, vsoc_hwc_layer* layers);
- // Returns yoffset of the handle or negative on error.
- int PostFrameBuffer(buffer_handle_t handle);
+ int32_t SetLayers(size_t num_layers, vsoc_hwc_layer* layers);
+ // Returns buffer offset or negative on error.
+ int32_t PostFrameBuffer(buffer_handle_t handle);
// Changes the broadcaster, gives the ability to report more than just the
- // yoffset by using a wrapper like the StatsKeepingComposer. Returns the old
+ // offset by using a wrapper like the StatsKeepingComposer. Returns the old
// broadcaster. Passing a NULL pointer will cause the composer to not
// broadcast at all.
FbBroadcaster ReplaceFbBroadcaster(FbBroadcaster);
diff --git a/guest/hals/hwcomposer/legacy/hwcomposer.cpp b/guest/hals/hwcomposer/legacy/hwcomposer.cpp
index 26f7706..693496d 100644
--- a/guest/hals/hwcomposer/legacy/hwcomposer.cpp
+++ b/guest/hals/hwcomposer/legacy/hwcomposer.cpp
@@ -49,10 +49,8 @@
#include <utils/String8.h>
#include <utils/Vector.h>
-#include <guest/hals/gralloc/legacy/gralloc_vsoc_priv.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h>
-#include <guest/libs/remoter/remoter_framework_pkt.h>
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
#include <sync/sync.h>
#include "base_composer.h"
@@ -61,6 +59,8 @@
#include "stats_keeper.h"
#include "vsoc_composer.h"
+using vsoc::framebuffer::FBBroadcastRegionView;
+
#ifdef USE_OLD_HWCOMPOSER
typedef cvd::BaseComposer InnerComposerType;
#else
@@ -245,20 +245,22 @@
#if VSOC_PLATFORM_SDK_AFTER(J)
static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev,
const uint32_t attribute) {
- const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
switch (attribute) {
case HWC_DISPLAY_VSYNC_PERIOD:
return pdev->vsync_period_ns;
case HWC_DISPLAY_WIDTH:
- return config.x_res();
+ return fb_broadcast->x_res();
case HWC_DISPLAY_HEIGHT:
- return config.y_res();
+ return fb_broadcast->y_res();
case HWC_DISPLAY_DPI_X:
- ALOGI("Reporting DPI_X of %d", config.dpi());
- return config.dpi() * 1000; // The number of pixels per thousand inches
+ ALOGI("Reporting DPI_X of %d", fb_broadcast->dpi());
+ // The number of pixels per thousand inches
+ return fb_broadcast->dpi() * 1000;
case HWC_DISPLAY_DPI_Y:
- ALOGI("Reporting DPI_Y of %d", config.dpi());
- return config.dpi() * 1000; // The number of pixels per thousand inches
+ ALOGI("Reporting DPI_Y of %d", fb_broadcast->dpi());
+ // The number of pixels per thousand inches
+ return fb_broadcast->dpi() * 1000;
default:
ALOGE("unknown display attribute %u", attribute);
return -EINVAL;
@@ -310,7 +312,7 @@
return -ENOMEM;
}
- int refreshRate = 60;
+ int refreshRate = FBBroadcastRegionView::GetInstance()->refresh_rate_hz();
dev->vsync_period_ns = 1000000000 / refreshRate;
struct timespec rt;
if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
diff --git a/guest/hals/hwcomposer/legacy/hwcomposer.mk b/guest/hals/hwcomposer/legacy/hwcomposer.mk
index d2d3832..3913d1d 100644
--- a/guest/hals/hwcomposer/legacy/hwcomposer.mk
+++ b/guest/hals/hwcomposer/legacy/hwcomposer.mk
@@ -18,7 +18,6 @@
LOCAL_VENDOR_MODULE := true
LOCAL_SHARED_LIBRARIES := \
- libvsocframebuffer \
libbase \
liblog \
libcutils \
@@ -26,6 +25,7 @@
libsync \
libhardware \
libjpeg \
+ vsoc_lib \
$(VSOC_STLPORT_LIBS)
LOCAL_STATIC_LIBRARIES := \
@@ -45,6 +45,7 @@
LOCAL_C_INCLUDES := \
device/google/cuttlefish_common \
+ device/google/cuttlefish_kernel \
external/libyuv/files/include \
bionic \
$(VSOC_STLPORT_INCLUDES)
diff --git a/guest/hals/hwcomposer/legacy/stats_keeper.cpp b/guest/hals/hwcomposer/legacy/stats_keeper.cpp
index 104f1ae..33ca28a 100644
--- a/guest/hals/hwcomposer/legacy/stats_keeper.cpp
+++ b/guest/hals/hwcomposer/legacy/stats_keeper.cpp
@@ -31,6 +31,7 @@
using cvd::time::Nanoseconds;
using cvd::time::Seconds;
using cvd::time::TimeDifference;
+using vsoc::layout::framebuffer::TimeSpec;
namespace cvd {
@@ -51,8 +52,33 @@
return *mset.rbegin();
}
+void TimeDifferenceToTimeSpec(const TimeDifference& td, TimeSpec* ts) {
+ ts->ts_sec = td.seconds();
+ ts->ts_nsec = td.subseconds_in_ns();
+}
+
} // namespace
+void StatsKeeper::GetLastCompositionStats(
+ vsoc::layout::framebuffer::CompositionStats* stats_p) {
+ if (stats_p) {
+ TimeDifferenceToTimeSpec(last_composition_stats_.prepare_start.SinceEpoch(),
+ &stats_p->prepare_start);
+ TimeDifferenceToTimeSpec(last_composition_stats_.prepare_end.SinceEpoch(),
+ &stats_p->prepare_end);
+ TimeDifferenceToTimeSpec(last_composition_stats_.set_start.SinceEpoch(),
+ &stats_p->set_start);
+ TimeDifferenceToTimeSpec(last_composition_stats_.set_end.SinceEpoch(),
+ &stats_p->set_end);
+ TimeDifferenceToTimeSpec(last_composition_stats_.last_vsync.SinceEpoch(),
+ &stats_p->last_vsync);
+
+ stats_p->num_prepare_calls = last_composition_stats_.num_prepare_calls;
+ stats_p->num_layers = last_composition_stats_.num_layers;
+ stats_p->num_hwcomposited_layers = last_composition_stats_.num_hwc_layers;
+ }
+}
+
StatsKeeper::StatsKeeper(TimeDifference timespan, int64_t vsync_base,
int32_t vsync_period)
: period_length_(timespan, 1),
diff --git a/guest/hals/hwcomposer/legacy/stats_keeper.h b/guest/hals/hwcomposer/legacy/stats_keeper.h
index 14d3602..397728a 100644
--- a/guest/hals/hwcomposer/legacy/stats_keeper.h
+++ b/guest/hals/hwcomposer/legacy/stats_keeper.h
@@ -15,13 +15,15 @@
* limitations under the License.
*/
-#include <android-base/thread_annotations.h>
-#include <common/libs/threads/cuttlefish_thread.h>
-#include <common/libs/time/monotonic_time.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h>
#include <deque>
#include <set>
+#include <android-base/thread_annotations.h>
+
+#include "common/libs/threads/cuttlefish_thread.h"
+#include "common/libs/time/monotonic_time.h"
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+
#include "hwcomposer_common.h"
namespace cvd {
@@ -60,6 +62,20 @@
cvd::time::Nanoseconds set_calls_time_;
};
+struct HWCCompositionStats {
+ cvd::time::MonotonicTimePoint prepare_start;
+ cvd::time::MonotonicTimePoint prepare_end;
+ cvd::time::MonotonicTimePoint set_start;
+ cvd::time::MonotonicTimePoint set_end;
+ cvd::time::MonotonicTimePoint last_vsync;
+ // There may be more than one call to prepare, the timestamps are with regards
+ // to the last one (the one that precedes the set call)
+ int num_prepare_calls;
+ int num_layers;
+ // The number of layers composed by the hwcomposer
+ int num_hwc_layers;
+};
+
class StatsKeeper {
public:
// The timespan parameter indicates for how long we keep stats about the past
@@ -78,9 +94,8 @@
void RecordSetStart();
void RecordSetEnd() EXCLUDES(mutex_);
- const CompositionStats& last_composition_stats() {
- return last_composition_stats_;
- }
+ void GetLastCompositionStats(
+ vsoc::layout::framebuffer::CompositionStats* stats_p);
// Calls to this function are synchronized with calls to 'RecordSetEnd' with a
// mutex. The other Record* functions do not need such synchronization because
@@ -96,7 +111,7 @@
int32_t vsync_period_;
// Data collected about ongoing composition. These variables are not accessed
// from Dump(), so they don't need to be guarded by a mutex.
- CompositionStats last_composition_stats_;
+ HWCCompositionStats last_composition_stats_;
// Aggregated performance data collected from past compositions. These
// variables are modified when a composition is completed and when old
@@ -142,9 +157,9 @@
composer_(vsync_base_timestamp, vsync_period_ns) {
// Don't let the composer broadcast by itself, allow it to return to collect
// the timings and broadcast then.
- composer_.ReplaceFbBroadcaster(NULL);
+ composer_.ReplaceFbBroadcaster(nullptr);
}
- ~StatsKeepingComposer() {}
+ ~StatsKeepingComposer() = default;
int PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) {
stats_keeper_.RecordPrepareStart(num_layers);
@@ -153,17 +168,19 @@
return num_hwc_layers;
}
- int SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+ int32_t SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+ vsoc::layout::framebuffer::CompositionStats stats;
stats_keeper_.RecordSetStart();
- int yoffset = composer_.SetLayers(num_layers, layers);
+ int32_t offset = composer_.SetLayers(num_layers, layers);
stats_keeper_.RecordSetEnd();
- if (yoffset >= 0) {
- VSoCFrameBufferControl::getInstance().BroadcastFrameBufferChanged(
- yoffset, &stats_keeper_.last_composition_stats());
+ if (offset >= 0) {
+ stats_keeper_.GetLastCompositionStats(&stats);
+ vsoc::framebuffer::FBBroadcastRegionView::GetInstance()
+ ->BroadcastNewFrame(static_cast<uint32_t>(offset), &stats);
} else {
- ALOGE("%s: Error on SetLayers(), yoffset: %d", __FUNCTION__, yoffset);
+ ALOGE("%s: Error on SetLayers(), offset: %d", __FUNCTION__, offset);
}
- return yoffset;
+ return offset;
}
void Dump(char* buff, int buff_len) {
diff --git a/guest/hals/hwcomposer/legacy/vsoc_composer.cpp b/guest/hals/hwcomposer/legacy/vsoc_composer.cpp
index f538336..e12c7a6 100644
--- a/guest/hals/hwcomposer/legacy/vsoc_composer.cpp
+++ b/guest/hals/hwcomposer/legacy/vsoc_composer.cpp
@@ -15,20 +15,25 @@
*/
#include "vsoc_composer.h"
-#include <cutils/log.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer.h>
-#include <guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h>
-#include <hardware/hwcomposer.h>
-#include <hardware/hwcomposer_defs.h>
-#include <libyuv.h>
-#include <system/graphics.h>
+
#include <algorithm>
#include <cstdlib>
#include <utility>
#include <vector>
+
+#include <cutils/log.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <libyuv.h>
+#include <system/graphics.h>
+
+#include "common/vsoc/lib/fb_bcast_region_view.h"
+
#include "geometry_utils.h"
#include "hwcomposer_common.h"
+using vsoc::framebuffer::FBBroadcastRegionView;
+
namespace cvd {
namespace {
@@ -215,9 +220,9 @@
uint8_t* src_y = src.buffer;
int stride_y = stride_in_pixels;
uint8_t* src_v = src_y + stride_y * src.height;
- int stride_v = VSoCFrameBuffer::align(stride_y / 2, 16);
+ int stride_v = FBBroadcastRegionView::align(stride_y / 2, 16);
uint8_t* src_u = src_v + stride_v * src.height / 2;
- int stride_u = VSoCFrameBuffer::align(stride_y / 2, 16);
+ int stride_u = FBBroadcastRegionView::align(stride_y / 2, 16);
// Adjust for crop
src_y += src.crop_y * stride_y + src.crop_x;
@@ -453,7 +458,7 @@
// these sizes are taken from the displayFrame rectangle which is always
// smaller than the framebuffer, the framebuffer in turn has aligned
// stride and these buffers are the size of the framebuffer.
- VSoCFrameBuffer::align(
+ FBBroadcastRegionView::align(
x_res * formatToBytesPerPixel(dst_priv_handle->format), 16));
dest_buffer_stack.push_back(tmp);
needed_tmp_buffers--;
@@ -475,7 +480,7 @@
// Make width and height match the crop sizes on the source
int src_width = src_layer_spec.crop_width;
int src_height = src_layer_spec.crop_height;
- int dst_stride = VSoCFrameBuffer::align(
+ int dst_stride = FBBroadcastRegionView::align(
src_width * formatToBytesPerPixel(dst_priv_handle->format), 16);
size_t needed_size = dst_stride * src_height;
dst_buffer_spec.width = src_width;
@@ -581,17 +586,17 @@
int32_t vsync_period_ns)
: BaseComposer(vsync_base_timestamp, vsync_period_ns),
tmp_buffer_(kNumTmpBufferPieces *
- VSoCFrameBuffer::getInstance().bufferSize()),
+ FBBroadcastRegionView::GetInstance()->buffer_size()),
next_hwc_framebuffer_(0) {
hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
reinterpret_cast<const hw_module_t**>(&gralloc_module_));
gralloc_module_->common.methods->open(
reinterpret_cast<const hw_module_t*>(gralloc_module_),
GRALLOC_HARDWARE_GPU0, reinterpret_cast<hw_device_t**>(&gralloc_dev_));
- for (int i = 0; i < VSoCFrameBuffer::kNumHwcBuffers; ++i) {
- buffer_handle_t tmp;
- gralloc_dev_->alloc_hwc_framebuffer(
- reinterpret_cast<alloc_device_t*>(gralloc_dev_), &tmp);
+ auto fb_broadcast = FBBroadcastRegionView::GetInstance();
+ buffer_handle_t tmp;
+ while (gralloc_dev_->alloc_hwc_framebuffer(
+ reinterpret_cast<alloc_device_t*>(gralloc_dev_), &tmp) == 0) {
hwc_framebuffers_.push_back(tmp);
}
}
@@ -650,7 +655,7 @@
return composited_layers_count;
}
-int VSoCComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+int32_t VSoCComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
int targetFbs = 0;
buffer_handle_t fb_handle = FindFrameBuffer(num_layers, layers);
if (!fb_handle) {
diff --git a/guest/hals/hwcomposer/legacy/vsoc_composer.h b/guest/hals/hwcomposer/legacy/vsoc_composer.h
index 892515c..9abe06c 100644
--- a/guest/hals/hwcomposer/legacy/vsoc_composer.h
+++ b/guest/hals/hwcomposer/legacy/vsoc_composer.h
@@ -15,13 +15,15 @@
* limitations under the License.
*/
-#include <hardware/gralloc.h>
-#include "base_composer.h"
-#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
-#include "hwcomposer_common.h"
-
#include <vector>
+#include <hardware/gralloc.h>
+
+#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
+
+#include "base_composer.h"
+#include "hwcomposer_common.h"
+
namespace cvd {
class VSoCComposer : public BaseComposer {
@@ -32,7 +34,7 @@
// override
int PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers);
// override
- int SetLayers(size_t num_layers, vsoc_hwc_layer* layers);
+ int32_t SetLayers(size_t num_layers, vsoc_hwc_layer* layers);
protected:
static const int kNumTmpBufferPieces;
diff --git a/guest/libs/legacy_framebuffer/Android.mk b/guest/libs/legacy_framebuffer/Android.mk
deleted file mode 100644
index 672879d..0000000
--- a/guest/libs/legacy_framebuffer/Android.mk
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2016 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.
-
-# Temporary, this library should go away once the new HALS are in place.
-
-vsocframebuffer_common_src_files := \
- vsoc_framebuffer.cpp \
- vsoc_framebuffer_control.cpp \
- RegionRegistry.cpp
-
-vsocframebuffer_common_c_flags := -Wall -Werror $(VSOC_VERSION_CFLAGS)
-
-vsocframebuffer_common_c_includes := \
- device/google/cuttlefish_common \
- device/google/cuttlefish_kernel
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libvsocframebuffer
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := ${vsocframebuffer_common_src_files}
-LOCAL_CFLAGS += ${vsocframebuffer_common_c_flags}
-LOCAL_C_INCLUDES := ${vsocframebuffer_common_c_includes} \
- $(VSOC_STLPORT_INCLUDES)
-
-LOCAL_STATIC_LIBRARIES := \
- libjsoncpp
-
-LOCAL_HEADER_LIBRARIES := \
- libhardware_headers
-
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- liblog \
- libutils \
- libcutils \
- cuttlefish_auto_resources \
- libcuttlefish_fs \
- vsoc_lib \
- $(VSOC_STLPORT_LIBS)
-
-# See b/67109557
-ifeq (true, $(TARGET_TRANSLATE_2ND_ARCH))
-LOCAL_MULTILIB := first
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/guest/libs/legacy_framebuffer/vsoc_framebuffer.cpp b/guest/libs/legacy_framebuffer/vsoc_framebuffer.cpp
deleted file mode 100644
index 1669715..0000000
--- a/guest/libs/legacy_framebuffer/vsoc_framebuffer.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2016 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 <guest/libs/platform_support/api_level_fixes.h>
-
-#define LOG_TAG "VSoCFrameBuffer"
-
-#include "vsoc_framebuffer.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <utils/String8.h>
-#include <cutils/log.h>
-#include <system/graphics.h>
-
-#include "common/vsoc/lib/fb_bcast_region_view.h"
-
-const char* const VSoCFrameBuffer::kFrameBufferPath =
- "/dev/userspace_framebuffer";
-
-const VSoCFrameBuffer & VSoCFrameBuffer::getInstance() {
- static VSoCFrameBuffer instance;
- instance.Configure();
- return instance;
-}
-
-
-VSoCFrameBuffer::VSoCFrameBuffer()
- : line_length_(-1) { }
-
-
-void VSoCFrameBuffer::Configure() {
- fb_region_view_ = vsoc::framebuffer::FBBroadcastRegionView::GetInstance();
- if (!fb_region_view_) {
- SLOGE("Failed to open broadcaster region");
- }
- line_length_ = align(x_res() * sizeof(Pixel));
-}
-
-
-int VSoCFrameBuffer::dpi() const {
- return fb_region_view_->dpi();
-}
-
-
-int VSoCFrameBuffer::x_res() const {
- return fb_region_view_->x_res();
-}
-
-
-int VSoCFrameBuffer::y_res() const {
- return fb_region_view_->y_res();
-}
-
-
-bool VSoCFrameBuffer::OpenFrameBuffer(int* frame_buffer_fd) {
- int fb_fd;
- if ((fb_fd = open(VSoCFrameBuffer::kFrameBufferPath, O_RDWR)) < 0) {
- SLOGE("Failed to open '%s' (%s)",
- VSoCFrameBuffer::kFrameBufferPath, strerror(errno));
- return false;
- }
-
- const VSoCFrameBuffer& config = VSoCFrameBuffer::getInstance();
-
- if (ftruncate(fb_fd, config.total_buffer_size()) < 0) {
- SLOGE("Failed to truncate framebuffer (%s)", strerror(errno));
- return false;
- }
-
- *frame_buffer_fd = fb_fd;
- return true;
-}
-
-
-bool VSoCFrameBuffer::OpenAndMapFrameBuffer(void** fb_memory,
- int* frame_buffer_fd) {
- int fb_fd;
- if (!VSoCFrameBuffer::OpenFrameBuffer(&fb_fd)) { return false; }
-
- size_t fb_size = VSoCFrameBuffer::getInstance().total_buffer_size();
-
- void* mmap_res = mmap(0, fb_size, PROT_READ, MAP_SHARED, fb_fd, 0);
- if (mmap_res == MAP_FAILED) {
- SLOGE("Failed to mmap framebuffer (%s)", strerror(errno));
- close(fb_fd);
- return false;
- }
-
- // Modify the pointers only after mmap succeeds.
- *fb_memory = mmap_res;
- *frame_buffer_fd = fb_fd;
-
- return true;
-}
-
-bool VSoCFrameBuffer::UnmapAndCloseFrameBuffer(void* fb_memory,
- int frame_buffer_fd) {
- size_t fb_size = VSoCFrameBuffer::getInstance().total_buffer_size();
- return munmap(fb_memory, fb_size) == 0 && close(frame_buffer_fd) == 0;
-}
-
-
-int VSoCFrameBuffer::hal_format() const {
- switch(bits_per_pixel()) {
- case 32:
- if (kRedShift) {
- return HAL_PIXEL_FORMAT_BGRA_8888;
- } else {
- return HAL_PIXEL_FORMAT_RGBX_8888;
- }
- default:
- return HAL_PIXEL_FORMAT_RGB_565;
- }
-}
-
-const char* pixel_format_to_string(int format) {
- switch (format) {
- // Formats that are universal across versions
- case HAL_PIXEL_FORMAT_RGBA_8888:
- return "RGBA_8888";
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return "RGBX_8888";
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return "BGRA_8888";
- case HAL_PIXEL_FORMAT_RGB_888:
- return "RGB_888";
- case HAL_PIXEL_FORMAT_RGB_565:
- return "RGB_565";
- case HAL_PIXEL_FORMAT_YV12:
- return "YV12";
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- return "YCrCb_420_SP";
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- return "YCbCr_422_SP";
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- return "YCbCr_422_I";
-
-#if VSOC_PLATFORM_SDK_AFTER(J)
- // First supported on JBMR1 (API 17)
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
- return "IMPLEMENTATION_DEFINED";
- case HAL_PIXEL_FORMAT_BLOB:
- return "BLOB";
-#endif
-#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
- // First supported on JBMR2 (API 18)
- case HAL_PIXEL_FORMAT_YCbCr_420_888:
- return "YCbCr_420_888";
- case HAL_PIXEL_FORMAT_Y8:
- return "Y8";
- case HAL_PIXEL_FORMAT_Y16:
- return "Y16";
-#endif
-#if VSOC_PLATFORM_SDK_AFTER(K)
- // Support was added in L (API 21)
- case HAL_PIXEL_FORMAT_RAW_OPAQUE:
- return "RAW_OPAQUE";
- // This is an alias for RAW_SENSOR in L and replaces it in M.
- case HAL_PIXEL_FORMAT_RAW16:
- return "RAW16";
- case HAL_PIXEL_FORMAT_RAW10:
- return "RAW10";
-#endif
-#if VSOC_PLATFORM_SDK_AFTER(L_MR1)
- case HAL_PIXEL_FORMAT_YCbCr_444_888:
- return "YCbCr_444_888";
- case HAL_PIXEL_FORMAT_YCbCr_422_888:
- return "YCbCr_422_888";
- case HAL_PIXEL_FORMAT_RAW12:
- return "RAW12";
- case HAL_PIXEL_FORMAT_FLEX_RGBA_8888:
- return "FLEX_RGBA_8888";
- case HAL_PIXEL_FORMAT_FLEX_RGB_888:
- return "FLEX_RGB_888";
-#endif
-
- // Formats that have been removed
-#if VSOC_PLATFORM_SDK_BEFORE(K)
- // Support was dropped on K (API 19)
- case HAL_PIXEL_FORMAT_RGBA_5551:
- return "RGBA_5551";
- case HAL_PIXEL_FORMAT_RGBA_4444:
- return "RGBA_4444";
-#endif
-#if VSOC_PLATFORM_SDK_BEFORE(L)
- // Renamed to RAW_16 in L. Both were present for L, but it was completely
- // removed in M.
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
- return "RAW_SENSOR";
-#endif
-#if VSOC_PLATFORM_SDK_AFTER(J_MR2) && VSOC_PLATFORM_SDK_BEFORE(M)
- // Supported K, L, and LMR1. Not supported on JBMR0, JBMR1, JBMR2, and M
- case HAL_PIXEL_FORMAT_sRGB_X_8888:
- return "sRGB_X_8888";
- case HAL_PIXEL_FORMAT_sRGB_A_8888:
- return "sRGB_A_8888";
-#endif
- }
- return "UNKNOWN";
-}
diff --git a/guest/libs/legacy_framebuffer/vsoc_framebuffer.h b/guest/libs/legacy_framebuffer/vsoc_framebuffer.h
deleted file mode 100644
index ce3ef6a..0000000
--- a/guest/libs/legacy_framebuffer/vsoc_framebuffer.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2016 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 <pthread.h>
-#include <sys/mman.h>
-
-#include <climits>
-#include <memory>
-
-struct private_handle_t;
-struct remoter_request_packet;
-
-namespace vsoc {
-namespace framebuffer {
-class FBBroadcastRegionView;
-}
-}
-
-inline size_t roundUpToPageSize(size_t x) {
- return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
-}
-
-class VSoCFrameBuffer {
-public:
- static const VSoCFrameBuffer& getInstance();
- VSoCFrameBuffer(const VSoCFrameBuffer&) = delete;
- VSoCFrameBuffer& operator=(const VSoCFrameBuffer&) = delete;
-
- static int align(int input, int alignment = kAlignment) {
- return (input + alignment - 1) & -alignment;
- }
-
- int bits_per_pixel() const {
- return kBitsPerPixel;
- }
-
- size_t bufferSize() const {
- return line_length_ * y_res();
- }
-
- int dpi() const;
-
- int hal_format() const;
-
- int line_length() const { return line_length_; }
-
- int total_buffer_size() const {
- return roundUpToPageSize(line_length_ * y_res_virtual() +
- VSoCFrameBuffer::kSwiftShaderPadding);
- }
-
- int x_res() const;
-
- int y_res() const;
-
- int y_res_virtual() const {
- return y_res() * kNumBuffers;
- }
-
- static const int kAlignment = 8;
- static const int kNumHwcBuffers = 3;
- // Without sync fences enabled surfaceflinger uses only 2 framebuffers,
- // regardless of how many are available
- static const int kNumSfBuffers = 3;
- static const int kNumBuffers = kNumHwcBuffers + kNumSfBuffers;
- static const char* const kFrameBufferPath;
-
- static const int kRedShift = 0;
- static const int kRedBits = 8;
- static const int kGreenShift = 8;
- static const int kGreenBits = 8;
- static const int kBlueShift = 16;
- static const int kBlueBits = 8;
- static const int kAlphaShift = 24;
- static const int kAlphaBits = 8;
- typedef uint32_t Pixel;
- static const int kSwiftShaderPadding = 4;
-
- // Opens the framebuffer file. Ensures the file has the appropriate size by
- // calling ftruncate.
- static bool OpenFrameBuffer(int* frame_buffer_fd);
-
- // Maps the framebuffer into memory. It's the caller's responsibility to
- // unmap the memory and close the file when done.
- static bool OpenAndMapFrameBuffer(void** fb_memory, int* frame_buffer_fd);
- static bool UnmapAndCloseFrameBuffer(void* fb_memory, int frame_buffer_fd);
-
-private:
- VSoCFrameBuffer();
- void Configure();
-
- std::shared_ptr<vsoc::framebuffer::FBBroadcastRegionView> fb_region_view_;
- static const int kBitsPerPixel = sizeof(Pixel) * CHAR_BIT;
- // Length of a scan-line in bytes.
- int line_length_;
-};
-
-const char* pixel_format_to_string(int format);
diff --git a/guest/libs/legacy_framebuffer/vsoc_framebuffer_control.cpp b/guest/libs/legacy_framebuffer/vsoc_framebuffer_control.cpp
deleted file mode 100644
index 83c9b00..0000000
--- a/guest/libs/legacy_framebuffer/vsoc_framebuffer_control.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2016 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 <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include <utils/String8.h>
-
-#define LOG_TAG "VSoCFrameBufferControl"
-#include <cutils/log.h>
-#include <system/graphics.h>
-
-#include "guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h"
-#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
-
-enum { NOT_YET = 0, IN_PROGRESS, DONE };
-
-struct FrameBufferControl {
- pthread_mutex_t mutex;
- pthread_cond_t cond_var;
- uint32_t seq_num;
- volatile int yoffset;
- volatile int initialized;
- volatile uint32_t buffer_bits;
- CompositionStats stats;
-};
-
-// __sync_lock_test_and_set is described to work on intel, but not on many other
-// targets.
-#define ATOMICALLY_SET(x, val) __sync_lock_test_and_set(&(x), (val))
-#define ATOMICALLY_COMPARE_AND_SWAP(x, old, val) \
- __sync_val_compare_and_swap(&(x), (old), (val))
-// fetch the value, don't modify it (or with 0)
-#define ATOMICALLY_GET(x) __sync_or_and_fetch(&(x), 0)
-
-const char* const VSoCFrameBufferControl::kFrameBufferControlPath =
- "/dev/framebuffer_control";
-
-VSoCFrameBufferControl& VSoCFrameBufferControl::getInstance() {
- static VSoCFrameBufferControl instance;
- // If not initialized before and fails to initialize now
- if (!instance.Initialize()) {
- LOG_ALWAYS_FATAL(
- "Unable to initialize the framebuffer control structure (%s)... "
- "aborting!",
- strerror(errno));
- }
- return instance;
-}
-
-uint32_t VSoCFrameBufferControl::GetAndSetNextAvailableBufferBit(uint32_t filter) {
- if (pthread_mutex_lock(&control_memory_->mutex)) {
- ALOGE("Failed to acquire lock on framebuffer control mutex (%s) - %s",
- strerror(errno), __FUNCTION__);
- return 0;
- }
- uint32_t bit = control_memory_->buffer_bits;
- bit &= filter;
- if (bit == filter) {
- // All bits in the filter are already set in the set
- bit = 0LU;
- } else {
- // Set available bits to 1
- bit = (bit^filter);
- // isolate first available bit
- bit &= ~bit + 1LU;
- // set it on bit set on shared memory
- control_memory_->buffer_bits |= bit;
- }
-
- pthread_mutex_unlock(&control_memory_->mutex);
- return bit;
-}
-
-int VSoCFrameBufferControl::UnsetBufferBits(uint32_t bits) {
- if (pthread_mutex_lock(&control_memory_->mutex)) {
- ALOGE("Failed to acquire lock on framebuffer control mutex (%s) - %s",
- strerror(errno), __FUNCTION__);
- return -1;
- }
-
- control_memory_->buffer_bits &= ~bits;
-
- pthread_mutex_unlock(&control_memory_->mutex);
- return 0;
-}
-
-VSoCFrameBufferControl::VSoCFrameBufferControl()
- : control_fd_(-1), control_memory_(NULL) {}
-
-namespace {
-
-bool MapFrameBufferControl(FrameBufferControl** control_memory_ptr,
- int* fbc_fd) {
- size_t control_size = sizeof(FrameBufferControl);
- mode_t fb_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
- int control_fd;
- if ((control_fd = open(VSoCFrameBufferControl::kFrameBufferControlPath, O_RDWR,
- fb_mode)) < 0) {
- ALOGE("Failed to open framebuffer control at %s (%s)",
- VSoCFrameBufferControl::kFrameBufferControlPath, strerror(errno));
- return false;
- }
-
- if (ftruncate(control_fd, sizeof(FrameBufferControl)) < 0) {
- ALOGE("Failed to truncate framebuffer control at %s (%s)",
- VSoCFrameBufferControl::kFrameBufferControlPath, strerror(errno));
- return false;
- }
-
- void* control_memory;
- control_memory =
- mmap(0, control_size, PROT_READ | PROT_WRITE, MAP_SHARED, control_fd, 0);
- if (control_memory == MAP_FAILED) {
- ALOGE("Failed to mmap framebuffer control (%s)", strerror(errno));
- close(control_fd);
- return false;
- }
-
- *control_memory_ptr = reinterpret_cast<FrameBufferControl*>(control_memory);
- *fbc_fd = control_fd;
-
- return true;
-}
-
-void UnmapFrameBufferControl(FrameBufferControl** control_memory_ptr,
- int* fbc_fd) {
- munmap(*control_memory_ptr, sizeof(FrameBufferControl));
- *control_memory_ptr = NULL;
- close(*fbc_fd);
- *fbc_fd = -1;
-}
-}
-
-bool VSoCFrameBufferControl::Initialize() {
- if (control_fd_ >= 0) {
- return true;
- }
-
- if (!MapFrameBufferControl(&control_memory_, &control_fd_)) {
- return false;
- }
-
- int initializing_state = ATOMICALLY_COMPARE_AND_SWAP(
- control_memory_->initialized, NOT_YET, IN_PROGRESS);
- switch (initializing_state) {
- case DONE:
- return true;
-
- case IN_PROGRESS: { // wait 1 sec and try again
- do {
- sleep(1);
- initializing_state = ATOMICALLY_GET(control_memory_->initialized);
- if (initializing_state != DONE) {
- ALOGW(
- "Framebuffer control structure has not yet been initialized "
- "after one second. Value of initialized flag: %d",
- initializing_state);
- }
- } while (initializing_state != DONE);
- return true;
- }
-
- case NOT_YET: { // flag set to IN_PROGRESS, proceed to initialize
- pthread_mutexattr_t mutex_attr;
- pthread_mutexattr_init(&mutex_attr);
- pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
- int retval = pthread_mutex_init(&(control_memory_->mutex), &mutex_attr);
- if (retval) {
- ALOGE("Failed to acquire lock on framebuffer control mutex (%s) - %s",
- strerror(errno), __FUNCTION__);
- UnmapFrameBufferControl(&control_memory_, &control_fd_);
- return false;
- }
- pthread_mutexattr_destroy(&mutex_attr);
-
- pthread_condattr_t cond_attr;
- pthread_condattr_init(&cond_attr);
- pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
- retval = pthread_cond_init(&(control_memory_->cond_var), &cond_attr);
- if (retval) {
- ALOGE("Failed to initialize cond var for framebuffer control (%s)",
- strerror(errno));
- pthread_mutex_destroy(&(control_memory_->mutex));
- UnmapFrameBufferControl(&control_memory_, &control_fd_);
- return false;
- }
- pthread_condattr_destroy(&cond_attr);
-
- ATOMICALLY_SET(control_memory_->buffer_bits, 0LU);
- ATOMICALLY_SET(control_memory_->seq_num, 0);
- ATOMICALLY_SET(control_memory_->initialized, DONE);
-
- return true;
- }
-
- default: { // unrecognized value
- ALOGE("Framebuffer control memory is corrupt, initialized = %d",
- initializing_state);
- UnmapFrameBufferControl(&control_memory_, &control_fd_);
- return false;
- }
- }
-
- return true;
-}
-
-int VSoCFrameBufferControl::GetCurrentYOffset() const {
- if (!control_memory_) return -1;
- return control_memory_->yoffset;
-}
-
-int VSoCFrameBufferControl::WaitForFrameBufferChangeSince(
- uint32_t previous_fb_seq,
- int* yoffset_p,
- uint32_t* fb_seq_p,
- CompositionStats* stats_p) {
- if (pthread_mutex_lock(&control_memory_->mutex)) {
- ALOGE("Failed to acquire lock on framebuffer control mutex (%s) - %s",
- strerror(errno), __FUNCTION__);
- return -1;
- }
- int retval = 0;
-
- while (control_memory_->seq_num == previous_fb_seq) {
- retval =
- pthread_cond_wait(&control_memory_->cond_var, &control_memory_->mutex);
- }
-
- if (fb_seq_p) {
- *fb_seq_p = control_memory_->seq_num;
- }
- if (yoffset_p) {
- *yoffset_p = control_memory_->yoffset;
- }
- if (stats_p) {
- *stats_p = control_memory_->stats;
- }
-
- pthread_mutex_unlock(&control_memory_->mutex);
- return retval;
-}
-
-int VSoCFrameBufferControl::WaitForFrameBufferChange(int* yoffset_p) {
- return WaitForFrameBufferChangeSince(
- control_memory_->seq_num, yoffset_p, NULL, NULL);
-}
-
-int VSoCFrameBufferControl::BroadcastFrameBufferChanged(int yoffset) {
- return BroadcastFrameBufferChanged(yoffset, NULL);
-}
-
-// increments the framebuffer sequential number, ensuring it's never zero
-static inline uint32_t seq_inc(uint32_t num) {
- ++num;
- return num? num: 1;
-}
-
-int VSoCFrameBufferControl::BroadcastFrameBufferChanged(
- int yoffset, const CompositionStats* stats) {
- if (pthread_mutex_lock(&control_memory_->mutex)) {
- ALOGE("Failed to acquire lock on framebuffer control mutex (%s)",
- strerror(errno));
- return -1;
- }
- control_memory_->yoffset = yoffset;
- control_memory_->seq_num = seq_inc(control_memory_->seq_num);
- if (stats) { control_memory_->stats = *stats; }
- pthread_cond_broadcast(&control_memory_->cond_var);
- pthread_mutex_unlock(&control_memory_->mutex);
-
- return 0;
-}
diff --git a/guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h b/guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h
deleted file mode 100644
index 5e1ec7e..0000000
--- a/guest/libs/legacy_framebuffer/vsoc_framebuffer_control.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2016 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 <common/libs/time/monotonic_time.h>
-
-struct FrameBufferControl;
-
-struct CompositionStats {
- cvd::time::MonotonicTimePoint prepare_start;
- cvd::time::MonotonicTimePoint prepare_end;
- cvd::time::MonotonicTimePoint set_start;
- cvd::time::MonotonicTimePoint set_end;
- cvd::time::MonotonicTimePoint last_vsync;
- // There may be more than one call to prepare, the timestamps are with regards to the last one (the one that precedes the set call)
- int num_prepare_calls;
- int num_layers;
- // The number of layers composed by the hwcomposer
- int num_hwc_layers;
-};
-
-class VSoCFrameBufferControl {
- public:
- static VSoCFrameBufferControl& getInstance();
-
- static const char* const kFrameBufferControlPath;
-
- // The framebuffer control structure mantains a bit set to keep track of the
- // buffers that have been allocated already. This function atomically finds an
- // unset (0) bit in the set, sets it to 1 and returns it. It will only
- // consider bits already set in the filter parameter.
- uint32_t GetAndSetNextAvailableBufferBit(uint32_t filter);
- // Returns 0 on success
- int UnsetBufferBits(uint32_t bits);
-
- // Returns the yoffset of the last framebuffer update or a negative number on
- // error.
- int GetCurrentYOffset() const;
- // Returns the value returned by the pthread_cond_wait, or -1 if the control
- // structure has not been initialized by the hwcomposer yet.
- int WaitForFrameBufferChange(int* yoffset_p);
- // Uses a sequential number to determine whether the client was notified of
- // the last framebuffer change and therefore needs to wait for a new one or if
- // it can just return with the last one. It also provides the timings of the
- // composition. Any NULL input parameters will be ignored. The sequential
- // numbers are guaranteed to never be zero, so a value of zero can be used to
- // get the last frame without waiting (useful when we want to get a frame for
- // the first time).
- int WaitForFrameBufferChangeSince(uint32_t previous_fb_seq,
- int* yoffset_p,
- uint32_t* fb_seq_p,
- CompositionStats* stats_p);
-
- // Returns 0 on success, a negative number on error.
- int BroadcastFrameBufferChanged(int yoffset);
-
- // Returns 0 on success, a negative number on error.
- int BroadcastFrameBufferChanged(int yoffset, const CompositionStats* stats);
-
- private:
- VSoCFrameBufferControl();
-
- // Map the control structure to memory and initialize its contents.
- bool Initialize();
-
- // FD for the frame buffer control.
- int control_fd_;
- // Pointer to the mapped frame buffer control.
- FrameBufferControl* control_memory_;
-
- // Disallow copy and assign
- VSoCFrameBufferControl(const VSoCFrameBufferControl&) {}
- VSoCFrameBufferControl& operator=(const VSoCFrameBufferControl&) {
- return *this;
- }
-};
diff --git a/host/commands/launch/fb_bcast_region_handler.cc b/host/commands/launch/fb_bcast_region_handler.cc
index 03f20b7..047c621 100644
--- a/host/commands/launch/fb_bcast_region_handler.cc
+++ b/host/commands/launch/fb_bcast_region_handler.cc
@@ -24,6 +24,7 @@
DEFINE_int32(x_res, 720, "Width of the screen in pixels");
DEFINE_int32(y_res, 1280, "Height of the screen in pixels");
DEFINE_int32(dpi, 160, "Pixels per inch for the screen");
+DEFINE_int32(refresh_rate_hz, 60, "Screen refresh rate in Hertz");
void InitializeFBBroadcastRegion() {
std::shared_ptr<vsoc::framebuffer::FBBroadcastRegionView> region =
@@ -37,4 +38,5 @@
dest->x_res = FLAGS_x_res;
dest->y_res = FLAGS_y_res;
dest->dpi = FLAGS_dpi;
+ dest->refresh_rate_hz = FLAGS_refresh_rate_hz;
}
diff --git a/host/config/vsoc_mem.json b/host/config/vsoc_mem.json
index f9cbc36..36f03ce 100644
--- a/host/config/vsoc_mem.json
+++ b/host/config/vsoc_mem.json
@@ -87,11 +87,29 @@
{
"device_name" : "gralloc_memory",
- "__comment" : "Holds the gralloc buffers",
+ "__comment" : "Holds the gralloc buffers. Size is 400 MB minus the size of the framebuffer",
"managed_by" : "gralloc_manager",
"current_version" : 0,
"min_compatible_version" : 0,
- "region_size" : 419430400,
+ "region_size" : 394850304,
+
+ "guest_to_host_signal_table" : {
+ "__comment" : "sizeof each node is based on common/libs/shm/lock.h",
+ "num_nodes_lg2" : 0
+ },
+
+ "host_to_guest_signal_table" : {
+ "num_nodes_lg2" : 0
+ }
+ },
+
+
+ {
+ "device_name" : "framebuffer",
+ "__comment" : "Holds the frame buffers. Size is enough to accomodate 6 buffers 800x1280 in RGBA format plus an extra page",
+ "current_version" : 0,
+ "min_compatible_version" : 0,
+ "region_size" : 24584192,
"guest_to_host_signal_table" : {
"__comment" : "sizeof each node is based on common/libs/shm/lock.h",