/* * 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 "base_composer.h" #include <string.h> #include <cutils/log.h> #include <hardware/gralloc.h> #include "common/vsoc/lib/screen_region_view.h" #include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h" using vsoc::screen::ScreenRegionView; namespace cvd { namespace { void BroadcastFrameBufferChanged(int index) { ScreenRegionView::GetInstance()->BroadcastNewFrame( static_cast<uint32_t>(index)); } } // namespace BaseComposer::BaseComposer(int64_t vsync_base_timestamp, int32_t vsync_period_ns) : vsync_base_timestamp_(vsync_base_timestamp), vsync_period_ns_(vsync_period_ns), fb_broadcaster_(BroadcastFrameBufferChanged) { hw_get_module(GRALLOC_HARDWARE_MODULE_ID, reinterpret_cast<const hw_module_t**>(&gralloc_module_)); } BaseComposer::~BaseComposer() {} FbBroadcaster BaseComposer::ReplaceFbBroadcaster(FbBroadcaster fb_broadcaster) { FbBroadcaster tmp = fb_broadcaster_; fb_broadcaster_ = fb_broadcaster; return tmp; } void BaseComposer::Dump(char* buff __unused, int buff_len __unused) {} void BaseComposer::Broadcast(int fb_index) { fb_broadcaster_(fb_index); } int BaseComposer::PostFrameBufferTarget(buffer_handle_t buffer_handle) { int fb_index = NextScreenBuffer(); if (fb_index < 0) { ALOGE("Could not get the next buffer. Is the screen region large enough?"); return -1; } auto screen_view = ScreenRegionView::GetInstance(); void* frame_buffer = screen_view->GetBuffer(fb_index); const private_handle_t* p_handle = reinterpret_cast<const private_handle_t*>(buffer_handle); void* buffer; int retval = gralloc_module_->lock(gralloc_module_, buffer_handle, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0, p_handle->x_res, p_handle->y_res, &buffer); if (retval != 0) { ALOGE("Got error code %d from lock function", retval); return -1; } memcpy(frame_buffer, buffer, screen_view->buffer_size()); Broadcast(fb_index); return 0; } // namespace cvd int BaseComposer::PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) { // find unsupported overlays for (size_t i = 0; i < num_layers; i++) { if (IS_TARGET_FRAMEBUFFER(layers[i].compositionType)) { continue; } layers[i].compositionType = HWC_FRAMEBUFFER; } return 0; } int 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 PostFrameBufferTarget(layers[idx].handle); } } return -1; } int BaseComposer::NextScreenBuffer() { int num_buffers = ScreenRegionView::GetInstance()->number_of_buffers(); last_frame_buffer_ = num_buffers > 0 ? (last_frame_buffer_ + 1) % num_buffers : -1; return last_frame_buffer_; } } // namespace cvd