1 /* 2 * Copyright 2014 NVIDIA Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include <errno.h> 29 #include <string.h> 30 31 #include "libkms-test.h" 32 33 static int kms_plane_probe(struct kms_plane *plane) 34 { 35 struct kms_device *device = plane->device; 36 drmModeObjectPropertiesPtr props; 37 drmModePlane *p; 38 unsigned int i; 39 40 p = drmModeGetPlane(device->fd, plane->id); 41 if (!p) 42 return -ENODEV; 43 44 /* TODO: allow dynamic assignment to CRTCs */ 45 if (p->crtc_id == 0) { 46 for (i = 0; i < device->num_crtcs; i++) { 47 if (p->possible_crtcs & (1 << i)) { 48 p->crtc_id = device->crtcs[i]->id; 49 break; 50 } 51 } 52 } 53 54 for (i = 0; i < device->num_crtcs; i++) { 55 if (device->crtcs[i]->id == p->crtc_id) { 56 plane->crtc = device->crtcs[i]; 57 break; 58 } 59 } 60 61 plane->formats = calloc(p->count_formats, sizeof(uint32_t)); 62 if (!plane->formats) 63 return -ENOMEM; 64 65 for (i = 0; i < p->count_formats; i++) 66 plane->formats[i] = p->formats[i]; 67 68 plane->num_formats = p->count_formats; 69 70 drmModeFreePlane(p); 71 72 props = drmModeObjectGetProperties(device->fd, plane->id, 73 DRM_MODE_OBJECT_PLANE); 74 if (!props) 75 return -ENODEV; 76 77 for (i = 0; i < props->count_props; i++) { 78 drmModePropertyPtr prop; 79 80 prop = drmModeGetProperty(device->fd, props->props[i]); 81 if (prop) { 82 if (strcmp(prop->name, "type") == 0) 83 plane->type = props->prop_values[i]; 84 85 drmModeFreeProperty(prop); 86 } 87 } 88 89 drmModeFreeObjectProperties(props); 90 91 return 0; 92 } 93 94 struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id) 95 { 96 struct kms_plane *plane; 97 98 plane = calloc(1, sizeof(*plane)); 99 if (!plane) 100 return NULL; 101 102 plane->device = device; 103 plane->id = id; 104 105 kms_plane_probe(plane); 106 107 return plane; 108 } 109 110 void kms_plane_free(struct kms_plane *plane) 111 { 112 free(plane); 113 } 114 115 int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb, 116 unsigned int x, unsigned int y) 117 { 118 struct kms_device *device = plane->device; 119 int err; 120 121 err = drmModeSetPlane(device->fd, plane->id, plane->crtc->id, fb->id, 122 0, x, y, fb->width, fb->height, 0 << 16, 123 0 << 16, fb->width << 16, fb->height << 16); 124 if (err < 0) 125 return -errno; 126 127 return 0; 128 } 129 130 bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format) 131 { 132 unsigned int i; 133 134 for (i = 0; i < plane->num_formats; i++) 135 if (plane->formats[i] == format) 136 return true; 137 138 return false; 139 } 140