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 #include <errno.h> 25 #include <string.h> 26 27 #include "libkms-test.h" 28 29 static int kms_plane_probe(struct kms_plane *plane) 30 { 31 struct kms_device *device = plane->device; 32 drmModeObjectPropertiesPtr props; 33 drmModePlane *p; 34 unsigned int i; 35 36 p = drmModeGetPlane(device->fd, plane->id); 37 if (!p) 38 return -ENODEV; 39 40 /* TODO: allow dynamic assignment to CRTCs */ 41 if (p->crtc_id == 0) { 42 for (i = 0; i < device->num_crtcs; i++) { 43 if (p->possible_crtcs & (1 << i)) { 44 p->crtc_id = device->crtcs[i]->id; 45 break; 46 } 47 } 48 } 49 50 for (i = 0; i < device->num_crtcs; i++) { 51 if (device->crtcs[i]->id == p->crtc_id) { 52 plane->crtc = device->crtcs[i]; 53 break; 54 } 55 } 56 57 plane->formats = calloc(p->count_formats, sizeof(uint32_t)); 58 if (!plane->formats) { 59 drmModeFreePlane(p); 60 return -ENOMEM; 61 } 62 63 for (i = 0; i < p->count_formats; i++) 64 plane->formats[i] = p->formats[i]; 65 66 plane->num_formats = p->count_formats; 67 68 drmModeFreePlane(p); 69 70 props = drmModeObjectGetProperties(device->fd, plane->id, 71 DRM_MODE_OBJECT_PLANE); 72 if (!props) 73 return -ENODEV; 74 75 for (i = 0; i < props->count_props; i++) { 76 drmModePropertyPtr prop; 77 78 prop = drmModeGetProperty(device->fd, props->props[i]); 79 if (prop) { 80 if (strcmp(prop->name, "type") == 0) 81 plane->type = props->prop_values[i]; 82 83 drmModeFreeProperty(prop); 84 } 85 } 86 87 drmModeFreeObjectProperties(props); 88 89 return 0; 90 } 91 92 struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id) 93 { 94 struct kms_plane *plane; 95 96 plane = calloc(1, sizeof(*plane)); 97 if (!plane) 98 return NULL; 99 100 plane->device = device; 101 plane->id = id; 102 103 kms_plane_probe(plane); 104 105 return plane; 106 } 107 108 void kms_plane_free(struct kms_plane *plane) 109 { 110 free(plane); 111 } 112 113 int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb, 114 unsigned int x, unsigned int y) 115 { 116 struct kms_device *device = plane->device; 117 int err; 118 119 err = drmModeSetPlane(device->fd, plane->id, plane->crtc->id, fb->id, 120 0, x, y, fb->width, fb->height, 0 << 16, 121 0 << 16, fb->width << 16, fb->height << 16); 122 if (err < 0) 123 return -errno; 124 125 return 0; 126 } 127 128 bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format) 129 { 130 unsigned int i; 131 132 for (i = 0; i < plane->num_formats; i++) 133 if (plane->formats[i] == format) 134 return true; 135 136 return false; 137 } 138