1d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang/* 2d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * Copyright (C) 2012 The Android Open Source Project 3d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * 4d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * Licensed under the Apache License, Version 2.0 (the "License"); 5d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * you may not use this file except in compliance with the License. 6d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * You may obtain a copy of the License at 7d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * 8d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * http://www.apache.org/licenses/LICENSE-2.0 9d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * 10d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * Unless required by applicable law or agreed to in writing, software 11d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * distributed under the License is distributed on an "AS IS" BASIS, 12d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * See the License for the specific language governing permissions and 14d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang * limitations under the License. 15d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang */ 16d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <pthread.h> 17d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <stdlib.h> 18d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <sys/time.h> 19d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <sys/resource.h> 20d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 21d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <cutils/log.h> 22d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <hardware/hwcomposer.h> 23d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang#include <sync/sync.h> 24d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 25d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstruct ranchu_hwc_composer_device_1 { 26d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hwc_composer_device_1_t base; // constant after init 27d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang const hwc_procs_t *procs; // constant after init 28d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_t vsync_thread; // constant after init 29d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int32_t vsync_period_ns; // constant after init 30d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang framebuffer_device_t* fbdev; // constant after init 31d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 32d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_mutex_t vsync_lock; 33d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang bool vsync_callback_enabled; // protected by this->vsync_lock 34d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang}; 35d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 36d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_prepare(hwc_composer_device_1_t* dev __unused, 37d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang size_t numDisplays, hwc_display_contents_1_t** displays) { 38d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 39d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (!numDisplays || !displays) return 0; 40d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 41d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY]; 42d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 43d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (!contents) return 0; 44d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 45d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang for (size_t i = 0; i < contents->numHwLayers; i++) { 46d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // We do not handle any layers, so set composition type of any non 47d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // HWC_FRAMEBUFFER_TARGET layer to to HWC_FRAMEBUFFER. 48d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { 49d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang continue; 50d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 51d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang contents->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 52d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 53d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 54d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 55d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 56d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_set(struct hwc_composer_device_1* dev,size_t numDisplays, 57d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hwc_display_contents_1_t** displays) { 58d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev; 59d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (!numDisplays || !displays) { 60d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 61d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 62d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 63d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY]; 64d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 65d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int retireFenceFd = -1; 66d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int err = 0; 67d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang for (size_t layer = 0; layer < contents->numHwLayers; layer++) { 68d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hwc_layer_1_t* fb_layer = &contents->hwLayers[layer]; 69d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 70d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int releaseFenceFd = -1; 71d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (fb_layer->acquireFenceFd > 0) { 72d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang const int kAcquireWarningMS= 3000; 73d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang err = sync_wait(fb_layer->acquireFenceFd, kAcquireWarningMS); 74d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (err < 0 && errno == ETIME) { 75d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("hwcomposer waited on fence %d for %d ms", 76d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang fb_layer->acquireFenceFd, kAcquireWarningMS); 77d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 78d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang close(fb_layer->acquireFenceFd); 79d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 80d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (fb_layer->compositionType != HWC_FRAMEBUFFER_TARGET) { 81d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("hwcomposer found acquire fence on layer %d which is not an" 82d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang "HWC_FRAMEBUFFER_TARGET layer", layer); 83d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 84d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 85d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang releaseFenceFd = dup(fb_layer->acquireFenceFd); 86d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang fb_layer->acquireFenceFd = -1; 87d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 88d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 89d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (fb_layer->compositionType != HWC_FRAMEBUFFER_TARGET) { 90d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang continue; 91d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 92d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 93d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->fbdev->post(pdev->fbdev, fb_layer->handle); 94d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang fb_layer->releaseFenceFd = releaseFenceFd; 95d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 96d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (releaseFenceFd > 0) { 97d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (retireFenceFd == -1) { 98d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang retireFenceFd = dup(releaseFenceFd); 99d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } else { 100d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int mergedFenceFd = sync_merge("hwc_set retireFence", 101d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang releaseFenceFd, retireFenceFd); 102d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang close(retireFenceFd); 103d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang retireFenceFd = mergedFenceFd; 104d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 105d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 106d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 107d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 108d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang contents->retireFenceFd = retireFenceFd; 109d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return err; 110d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 111d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 112d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_query(struct hwc_composer_device_1* dev, int what, int* value) { 113d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = 114d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang (struct ranchu_hwc_composer_device_1*)dev; 115d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 116d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang switch (what) { 117d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_BACKGROUND_LAYER_SUPPORTED: 118d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // we do not support the background layer 119d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang value[0] = 0; 120d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang break; 121d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_VSYNC_PERIOD: 122d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang value[0] = pdev->vsync_period_ns; 123d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang break; 124d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang default: 125d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // unsupported query 126d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what); 127d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -EINVAL; 128d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 129d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 130d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 131d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 132d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_event_control(struct hwc_composer_device_1* dev, int dpy __unused, 133d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int event, int enabled) { 134d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = 135d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang (struct ranchu_hwc_composer_device_1*)dev; 136d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int ret = -EINVAL; 137d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 138d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // enabled can only be 0 or 1 139d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (!(enabled & ~1)) { 140d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (event == HWC_EVENT_VSYNC) { 141d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_mutex_lock(&pdev->vsync_lock); 142d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->vsync_callback_enabled=enabled; 143d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_mutex_unlock(&pdev->vsync_lock); 144d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ret = 0; 145d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 146d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 147d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return ret; 148d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 149d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 150d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_blank(struct hwc_composer_device_1* dev __unused, int disp, 151d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int blank __unused) { 152d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (disp != HWC_DISPLAY_PRIMARY) { 153d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -EINVAL; 154d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 155d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 156d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 157d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 158d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic void hwc_dump(hwc_composer_device_1* dev __unused, char* buff __unused, 159d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int buff_len __unused) { 160d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // This is run when running dumpsys. 161d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang // No-op for now. 162d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 163d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 164d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 165d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_get_display_configs(struct hwc_composer_device_1* dev __unused, 166d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int disp, uint32_t* configs, size_t* numConfigs) { 167d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (*numConfigs == 0) { 168d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 169d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 170d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 171d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (disp == HWC_DISPLAY_PRIMARY) { 172d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang configs[0] = 0; 173d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang *numConfigs = 1; 174d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 175d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 176d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 177d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -EINVAL; 178d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 179d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 180d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 181d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int32_t hwc_attribute(struct ranchu_hwc_composer_device_1* pdev, 182d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang const uint32_t attribute) { 183d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang switch(attribute) { 184d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_DISPLAY_VSYNC_PERIOD: 185d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return pdev->vsync_period_ns; 186d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_DISPLAY_WIDTH: 187d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return pdev->fbdev->width; 188d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_DISPLAY_HEIGHT: 189d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return pdev->fbdev->height; 190d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_DISPLAY_DPI_X: 191d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return pdev->fbdev->xdpi*1000; 192d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang case HWC_DISPLAY_DPI_Y: 193d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return pdev->fbdev->ydpi*1000; 194d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang default: 195d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("unknown display attribute %u", attribute); 196d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -EINVAL; 197d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 198d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 199d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 200d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_get_display_attributes(struct hwc_composer_device_1* dev __unused, 201d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int disp, uint32_t config __unused, 202d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang const uint32_t* attributes, int32_t* values) { 203d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 204d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev; 205d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { 206d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (disp == HWC_DISPLAY_PRIMARY) { 207d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang values[i] = hwc_attribute(pdev, attributes[i]); 208d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } else { 209d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("unknown display type %u", disp); 210d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -EINVAL; 211d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 212d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 213d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 214d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 215d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 216d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 217d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_close(hw_device_t* dev) { 218d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev; 219d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_kill(pdev->vsync_thread, SIGTERM); 220d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_join(pdev->vsync_thread, NULL); 221d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang free(dev); 222d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return 0; 223d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 224d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 225d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic void* hwc_vsync_thread(void* data) { 226d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)data; 227d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 228d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 229d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct timespec rt; 230d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { 231d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("%s:%d error in vsync thread clock_gettime: %s", 232d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang __FILE__, __LINE__, strerror(errno)); 233d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 234d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang const int log_interval = 60; 235d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int64_t last_logged = rt.tv_sec; 236d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int sent = 0; 237d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int last_sent = 0; 238d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang bool vsync_enabled = false; 239d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct timespec wait_time; 240d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang wait_time.tv_sec = 0; 241d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang wait_time.tv_nsec = pdev->vsync_period_ns; 242d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 243d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang while (true) { 244d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int err = nanosleep(&wait_time, NULL); 245d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (err == -1) { 246d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (errno == EINTR) { 247d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang break; 248d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 249d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("error in vsync thread: %s", strerror(errno)); 250d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 251d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 252d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_mutex_lock(&pdev->vsync_lock); 253d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang vsync_enabled = pdev->vsync_callback_enabled; 254d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_mutex_unlock(&pdev->vsync_lock); 255d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 256d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (!vsync_enabled) { 257d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang continue; 258d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 259d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 260d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { 261d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("%s:%d error in vsync thread clock_gettime: %s", 262d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang __FILE__, __LINE__, strerror(errno)); 263d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 264d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 265d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec; 266d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->procs->vsync(pdev->procs, 0, timestamp); 267d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (rt.tv_sec - last_logged >= log_interval) { 268d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGD("hw_composer sent %d syncs in %ds", sent - last_sent, rt.tv_sec - last_logged); 269d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang last_logged = rt.tv_sec; 270d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang last_sent = sent; 271d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 272d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ++sent; 273d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 274d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 275d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return NULL; 276d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 277d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 278d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic void hwc_register_procs(struct hwc_composer_device_1* dev, 279d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hwc_procs_t const* procs) { 280d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev; 281d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->procs = procs; 282d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 283d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 284d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic int hwc_open(const struct hw_module_t* module, const char* name, 285d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang struct hw_device_t** device) { 286d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang int ret = 0; 287d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 288d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 289d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("%s called with bad name %s", __FUNCTION__, name); 290d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -EINVAL; 291d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 292d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 293d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ranchu_hwc_composer_device_1 *pdev = new ranchu_hwc_composer_device_1(); 294d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (!pdev) { 295d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("%s failed to allocate dev", __FUNCTION__); 296d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return -ENOMEM; 297d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 298d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 299d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.common.tag = HARDWARE_DEVICE_TAG; 300d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.common.version = HWC_DEVICE_API_VERSION_1_1; 301d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.common.module = const_cast<hw_module_t *>(module); 302d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.common.close = hwc_close; 303d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 304d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.prepare = hwc_prepare; 305d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.set = hwc_set; 306d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.eventControl = hwc_event_control; 307d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.blank = hwc_blank; 308d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.query = hwc_query; 309d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.registerProcs = hwc_register_procs; 310d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.dump = hwc_dump; 311d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.getDisplayConfigs = hwc_get_display_configs; 312d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->base.getDisplayAttributes = hwc_get_display_attributes; 313d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 314d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->vsync_period_ns = 1000*1000*1000/60; // vsync is 60 hz 315d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 316d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hw_module_t const* hw_module; 317d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module); 318d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (ret != 0) { 319d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("ranchu_hw_composer hwc_open %s module not found", GRALLOC_HARDWARE_MODULE_ID); 320d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return ret; 321d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 322d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ret = framebuffer_open(hw_module, &pdev->fbdev); 323d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (ret != 0) { 324d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("ranchu_hw_composer hwc_open could not open framebuffer"); 325d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 326d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 327d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pthread_mutex_init(&pdev->vsync_lock, NULL); 328d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang pdev->vsync_callback_enabled = false; 329d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 330d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ret = pthread_create (&pdev->vsync_thread, NULL, hwc_vsync_thread, pdev); 331d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang if (ret) { 332d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang ALOGE("ranchu_hw_composer could not start vsync_thread\n"); 333d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 334d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 335d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang *device = &pdev->base.common; 336d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 337d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang return ret; 338d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang} 339d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 340d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 341d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langstatic struct hw_module_methods_t hwc_module_methods = { 342d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang open: hwc_open, 343d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang}; 344d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang 345d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Langhwc_module_t HAL_MODULE_INFO_SYM = { 346d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang common: { 347d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang tag: HARDWARE_MODULE_TAG, 348d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang module_api_version: HWC_MODULE_API_VERSION_0_1, 349d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang hal_api_version: HARDWARE_HAL_API_VERSION, 350d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang id: HWC_HARDWARE_MODULE_ID, 351d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang name: "Android Emulator hwcomposer module", 352d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang author: "The Android Open Source Project", 353d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang methods: &hwc_module_methods, 354d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang } 355d4d0af6f3f24fb7e50cf514e486c7c6e953b6a05Joshua Lang}; 356