summaryrefslogtreecommitdiff
path: root/hwc2/common/devices/VirtualDevice.cpp (plain)
blob: 24db6aa7a7d5ae95ed15d1dac107745be8b5b459
1/*
2// Copyright (c) 2014 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16// This file is modified by Amlogic, Inc. 2017.01.17.
17*/
18
19#include <HwcTrace.h>
20#include <Hwcomposer.h>
21#include <VirtualDevice.h>
22#include <Utils.h>
23#include <sync/sync.h>
24
25namespace android {
26namespace amlogic {
27
28VirtualDevice::VirtualDevice(Hwcomposer& hwc)
29 : mHwc(hwc),
30 mId(HWC_DISPLAY_VIRTUAL),
31 mIsConnected(false),
32 mInitialized(false),
33 mWidth(0),
34 mHeight(0),
35 mFormat(0),
36 mRetireFence(-1)
37{
38 CTRACE();
39 mName = "Virtual";
40
41 // set capacity of layers, layer's changed type, layer's changed request.
42 mHwcLayersChangeType.setCapacity(LAYER_MAX_NUM_CHANGE_TYPE);
43 mHwcLayers.setCapacity(LAYER_MAX_NUM_SUPPORT);
44}
45
46VirtualDevice::~VirtualDevice()
47{
48 CTRACE();
49}
50
51bool VirtualDevice::initialize() {
52 CTRACE();
53
54 mInitialized = true;
55 return true;
56}
57
58void VirtualDevice::deinitialize() {
59 CTRACE();
60 mInitialized = false;
61}
62
63HwcLayer* VirtualDevice::getLayerById(hwc2_layer_t layerId) {
64 HwcLayer* layer = NULL;
65
66 layer = mHwcLayers.valueFor(layerId);
67 if (!layer) ETRACE("getLayerById %lld error!", layerId);
68
69 return layer;
70}
71
72int32_t VirtualDevice::acceptDisplayChanges() {
73 HwcLayer* layer = NULL;
74
75 for (uint32_t i=0; i<mHwcLayersChangeType.size(); i++) {
76 hwc2_layer_t layerId = mHwcLayersChangeType.keyAt(i);
77 layer = mHwcLayersChangeType.valueAt(i);
78 if (layer) {
79 if (layer->getCompositionType() != HWC2_COMPOSITION_CLIENT) {
80 layer->setCompositionType(HWC2_COMPOSITION_CLIENT);
81 }
82 }
83 }
84 // reset layer changed or requested to zero.
85 mHwcLayersChangeType.clear();
86
87 return HWC2_ERROR_NONE;
88}
89
90bool VirtualDevice::createLayer(hwc2_layer_t* outLayer) {
91 HwcLayer* layer = new HwcLayer(mId);
92
93 if (layer == NULL || !layer->initialize()) {
94 ETRACE("createLayer: failed !");
95 return false;
96 }
97
98 hwc2_layer_t layerId = reinterpret_cast<hwc2_layer_t>(layer);
99 mHwcLayers.add(layerId, layer);
100 *outLayer = layerId;
101 return true;
102}
103
104bool VirtualDevice::destroyLayer(hwc2_layer_t layerId) {
105 //HwcLayer* layer = reinterpret_cast<HwcLayer*>(layerId);
106 HwcLayer* layer = mHwcLayers.valueFor(layerId);
107
108 if (layer == NULL) {
109 ETRACE("destroyLayer: no Hwclayer found (%d)", layerId);
110 return false;
111 }
112
113 mHwcLayers.removeItem(layerId);
114 DEINIT_AND_DELETE_OBJ(layer);
115 return true;
116}
117
118int32_t VirtualDevice::getActiveConfig(
119 hwc2_config_t* outConfig) {
120
121 return HWC2_ERROR_NONE;
122}
123
124int32_t VirtualDevice::getChangedCompositionTypes(
125 uint32_t* outNumElements,
126 hwc2_layer_t* outLayers,
127 int32_t* /*hwc2_composition_t*/ outTypes) {
128 HwcLayer* layer = NULL;
129
130 // if outLayers or outTypes were NULL, the number of layers and types which would have been returned.
131 if (NULL == outLayers || NULL == outTypes) {
132 *outNumElements = mHwcLayersChangeType.size();
133 } else {
134 for (uint32_t i=0; i<mHwcLayersChangeType.size(); i++) {
135 hwc2_layer_t layerId = mHwcLayersChangeType.keyAt(i);
136 layer = mHwcLayersChangeType.valueAt(i);
137 if (layer) {
138 if (layer->getCompositionType() != HWC2_COMPOSITION_CLIENT) {
139 // change all other device type to client.
140 outLayers[i] = layerId;
141 outTypes[i] = HWC2_COMPOSITION_CLIENT;
142 continue;
143 }
144 }
145 }
146
147 if (mHwcLayersChangeType.size() > 0) {
148 DTRACE("There are %d layers type has changed.", mHwcLayersChangeType.size());
149 *outNumElements = mHwcLayersChangeType.size();
150 } else {
151 DTRACE("No layers compositon type changed.");
152 }
153 }
154
155 return HWC2_ERROR_NONE;
156}
157
158int32_t VirtualDevice::getClientTargetSupport(
159 uint32_t width,
160 uint32_t height,
161 int32_t /*android_pixel_format_t*/ format,
162 int32_t /*android_dataspace_t*/ dataspace) {
163
164 // TODO: ?
165 return HWC2_ERROR_NONE;
166}
167
168int32_t VirtualDevice::getColorModes(
169 uint32_t* outNumModes,
170 int32_t* /*android_color_mode_t*/ outModes) {
171 return HWC2_ERROR_NONE;
172}
173
174int32_t VirtualDevice::getDisplayAttribute(
175 hwc2_config_t config,
176 int32_t /*hwc2_attribute_t*/ attribute,
177 int32_t* outValue) {
178 Mutex::Autolock _l(mLock);
179
180 if (!mIsConnected) {
181 ETRACE("display %d is not connected.", mId);
182 }
183
184 // TODO: HWC2_ERROR_BAD_CONFIG?
185 switch (attribute) {
186 case HWC2_ATTRIBUTE_VSYNC_PERIOD:
187 *outValue = 1e9 / 60;
188 ETRACE("refresh period: %d", *outValue);
189 break;
190 case HWC2_ATTRIBUTE_WIDTH:
191 *outValue = mWidth;
192 break;
193 case HWC2_ATTRIBUTE_HEIGHT:
194 *outValue = mHeight;
195 break;
196 case HWC2_ATTRIBUTE_DPI_X:
197 *outValue = 160;
198 break;
199 case HWC2_ATTRIBUTE_DPI_Y:
200 *outValue = 160;
201 break;
202 default:
203 ETRACE("unknown display attribute %u", attribute);
204 *outValue = -1;
205 break;
206 }
207
208 return HWC2_ERROR_NONE;
209}
210
211int32_t VirtualDevice::getDisplayConfigs(
212 uint32_t* outNumConfigs,
213 hwc2_config_t* outConfigs) {
214 Mutex::Autolock _l(mLock);
215
216 if (!mIsConnected) {
217 ETRACE("display %d is not connected.", mId);
218 }
219
220 if (NULL != outConfigs) outConfigs[0] = 0;
221 *outNumConfigs = 1;
222
223 return HWC2_ERROR_NONE;
224}
225
226int32_t VirtualDevice::getDisplayName(
227 uint32_t* outSize,
228 char* outName) {
229 return HWC2_ERROR_NONE;
230}
231
232int32_t VirtualDevice::getDisplayRequests(
233 int32_t* /*hwc2_display_request_t*/ outDisplayRequests,
234 uint32_t* outNumElements,
235 hwc2_layer_t* outLayers,
236 int32_t* /*hwc2_layer_request_t*/ outLayerRequests) {
237 *outNumElements = 0;
238
239 return HWC2_ERROR_NONE;
240}
241
242int32_t VirtualDevice::getDisplayType(
243 int32_t* /*hwc2_display_type_t*/ outType) {
244 if (!mIsConnected) {
245 ETRACE("display %d is not connected.", mId);
246 }
247
248 *outType = HWC2_DISPLAY_TYPE_VIRTUAL;
249 return HWC2_ERROR_NONE;
250}
251
252int32_t VirtualDevice::getDozeSupport(
253 int32_t* outSupport) {
254 return HWC2_ERROR_NONE;
255}
256
257int32_t VirtualDevice::getHdrCapabilities(
258 uint32_t* outNumTypes,
259 int32_t* /*android_hdr_t*/ outTypes,
260 float* outMaxLuminance,
261 float* outMaxAverageLuminance,
262 float* outMinLuminance) {
263 return HWC2_ERROR_NONE;
264}
265
266int32_t VirtualDevice::getReleaseFences(
267 uint32_t* outNumElements,
268 hwc2_layer_t* outLayers,
269 int32_t* outFences) {
270
271 //No hw compose for virtual display.
272 *outNumElements= 0;
273 return HWC2_ERROR_NONE;
274}
275
276int32_t VirtualDevice::presentDisplay(
277 int32_t* outRetireFence) {
278 if (!mIsConnected)
279 return HWC2_ERROR_BAD_DISPLAY;
280
281 if (!mVirtualHnd) {
282 ETRACE("virtual display handle is null.");
283 return HWC2_ERROR_NO_RESOURCES;
284 }
285
286 if (private_handle_t::validate(mVirtualHnd) < 0)
287 return HWC2_ERROR_NO_RESOURCES;
288
289 if (mTargetAcquireFence > -1 && mVirtualReleaseFence > -1) {
290 mRetireFence = sync_merge("VirtualDevice-2", mTargetAcquireFence, mVirtualReleaseFence);
291 } else if (mTargetAcquireFence > -1) {
292 mRetireFence = sync_merge("VirtualDevice-0", mTargetAcquireFence, mTargetAcquireFence);
293 } else if (mVirtualReleaseFence > -1) {
294 mRetireFence = sync_merge("VirtualDevice-1", mVirtualReleaseFence, mVirtualReleaseFence);
295 } else {
296 mRetireFence = -1;
297 }
298
299 *outRetireFence = mRetireFence;
300
301 DTRACE("VirtualDevice::presentDisplay retire fence %d", mRetireFence);
302
303 if (mTargetAcquireFence > -1) {
304 close(mTargetAcquireFence);
305 mTargetAcquireFence = -1;
306 }
307 if (mVirtualReleaseFence > -1) {
308 close(mVirtualReleaseFence);
309 mVirtualReleaseFence = -1;
310 }
311
312 //reset layers' acquire fence.
313 HwcLayer * layer = NULL;
314 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
315 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
316 layer = mHwcLayers.valueAt(i);
317 if (layer != NULL) {
318 close(layer->getAcquireFence());
319 layer->resetAcquireFence();
320 }
321 }
322
323 return HWC2_ERROR_NONE;
324}
325
326int32_t VirtualDevice::setActiveConfig(
327 hwc2_config_t config) {
328 return HWC2_ERROR_NONE;
329}
330
331int32_t VirtualDevice::setClientTarget(
332 buffer_handle_t target,
333 int32_t acquireFence,
334 int32_t /*android_dataspace_t*/ dataspace,
335 hwc_region_t damage) {
336
337 DTRACE("VirtualDevice::setClientTarget %p, %d", target, acquireFence);
338
339 if (mTargetAcquireFence > -1) {
340 close(mTargetAcquireFence);
341 mTargetAcquireFence = -1;
342 }
343
344 if (!mIsConnected)
345 return HWC2_ERROR_BAD_DISPLAY;
346
347 if (target && private_handle_t::validate(target) < 0) {
348 return HWC2_ERROR_BAD_PARAMETER;
349 }
350
351 if (NULL != target) {
352 mClientTargetHnd = target;
353 mClientTargetDamageRegion = damage;
354 mTargetAcquireFence = acquireFence;
355 } else {
356 DTRACE("client target is null!, no need to update this frame.");
357 }
358
359 return HWC2_ERROR_NONE;
360}
361
362int32_t VirtualDevice::setColorMode(
363 int32_t /*android_color_mode_t*/ mode) {
364 return HWC2_ERROR_NONE;
365}
366
367int32_t VirtualDevice::setColorTransform(
368 const float* matrix,
369 int32_t /*android_color_transform_t*/ hint) {
370 return HWC2_ERROR_NONE;
371}
372
373int32_t VirtualDevice::setPowerMode(
374 int32_t /*hwc2_power_mode_t*/ mode){
375 return HWC2_ERROR_NONE;
376}
377
378bool VirtualDevice::vsyncControl(bool enabled) {
379 RETURN_FALSE_IF_NOT_INIT();
380
381 return true;
382}
383
384int32_t VirtualDevice::validateDisplay(uint32_t* outNumTypes,
385 uint32_t* outNumRequests) {
386 HwcLayer* layer = NULL;
387
388 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
389 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
390 layer = mHwcLayers.valueAt(i);
391 if (layer) {
392 // Virtual Display.
393 if (layer->getCompositionType() != HWC2_COMPOSITION_CLIENT) {
394 // change all other device type to client.
395 mHwcLayersChangeType.add(layerId, layer);
396 continue;
397 }
398 }
399 }
400
401 // No requests.
402 *outNumRequests = 0;
403
404 if (mHwcLayersChangeType.size() > 0) {
405 DTRACE("there are %d layer types has changed.", mHwcLayersChangeType.size());
406 *outNumTypes = mHwcLayersChangeType.size();
407 return HWC2_ERROR_HAS_CHANGES;
408 }
409
410 return HWC2_ERROR_NONE;
411}
412
413int32_t VirtualDevice::setCursorPosition(
414 hwc2_layer_t layerId,
415 int32_t x,
416 int32_t y) {
417 Mutex::Autolock _l(mLock);
418 return HWC2_ERROR_NONE;
419}
420
421bool VirtualDevice::updateDisplayConfigs()
422{
423 Mutex::Autolock _l(mLock);
424 return true;
425}
426
427void VirtualDevice::onVsync(int64_t timestamp) {
428 // dont need implement now.
429}
430
431int32_t VirtualDevice::createVirtualDisplay(
432 uint32_t width,
433 uint32_t height,
434 int32_t* /*android_pixel_format_t*/ format,
435 hwc2_display_t* outDisplay) {
436 mIsConnected = true;
437 mWidth = width;
438 mHeight = height;
439 mFormat = *format;
440 mVirtualReleaseFence= -1;
441 mRetireFence = -1;
442 mTargetAcquireFence = -1;
443 *outDisplay = HWC_DISPLAY_VIRTUAL;
444
445 return HWC2_ERROR_NONE;
446}
447
448int32_t VirtualDevice::destroyVirtualDisplay(
449 hwc2_display_t display) {
450 if (display != HWC_DISPLAY_VIRTUAL) {
451 return HWC2_ERROR_BAD_PARAMETER;
452 }
453 mIsConnected = false;
454 mWidth = 0;
455 mHeight = 0;
456 mFormat = 0;
457
458 //release fence.
459 if (mRetireFence > -1) {
460 close(mRetireFence);
461 mRetireFence = -1;
462 }
463 if (mVirtualReleaseFence > -1) {
464 close(mVirtualReleaseFence);
465 mVirtualReleaseFence = -1;
466 }
467 if (mTargetAcquireFence > -1) {
468 close(mTargetAcquireFence);
469 mTargetAcquireFence = -1;
470 }
471
472 //release layers.
473 if (!mHwcLayers.isEmpty()) {
474 int i = 0;
475 HwcLayer* layer = NULL;
476 for (i = 0; i < mHwcLayers.size(); i++) {
477 layer = mHwcLayers[i];
478 DEINIT_AND_DELETE_OBJ(layer);
479 }
480 mHwcLayers.clear();
481 }
482
483 return HWC2_ERROR_NONE;
484}
485
486int32_t VirtualDevice::setOutputBuffer(
487 buffer_handle_t buffer, int32_t releaseFence) {
488 DTRACE("VirtualDevice::setOutputBuffer");
489
490 if (mVirtualReleaseFence > -1) {
491 close(mVirtualReleaseFence);
492 mVirtualReleaseFence = -1;
493 }
494
495 if (!mIsConnected)
496 return HWC2_ERROR_BAD_DISPLAY;
497
498 if (NULL == buffer) {
499 ETRACE("Virtual Display output buffer target is null!, no need to update this frame.");
500 return HWC2_ERROR_BAD_PARAMETER;
501 }
502
503 if (buffer && private_handle_t::validate(buffer) < 0) {
504 ETRACE("buffer handle is invalid");
505 return HWC2_ERROR_BAD_PARAMETER;
506 }
507
508 mVirtualHnd = buffer;
509 mVirtualReleaseFence = releaseFence;
510 DTRACE("VirtualDevice setOutputBuffer %d, %p ", releaseFence, buffer);
511 return HWC2_ERROR_NONE;
512}
513
514void VirtualDevice::dump(Dump& d) {
515 Mutex::Autolock _l(mLock);
516 d.append("----------------------------------------------------------"
517 "-------------------------------------------------------------------\n");
518 d.append("Device Name: %s (%s)\n", mName,
519 mIsConnected ? "connected" : "disconnected");
520
521 if (mIsConnected) {
522 d.append(" Layers state:\n");
523 d.append(" numLayers=%zu\n", mHwcLayers.size());
524 d.append(" numChangedTypeLayers=%zu\n", mHwcLayersChangeType.size());
525 if (mHwcLayers.size() > 0) {
526 d.append(
527 " type | handle | zorder | ds | alpa | tr | blnd |"
528 " source crop (l,t,r,b) | frame \n"
529 " -------------+--------------+------------+----+------+----+------+"
530 "--------------------------------+------------------------\n");
531 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
532 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
533 HwcLayer *layer = mHwcLayers.valueAt(i);
534 if (layer) layer->dump(d);
535 }
536 }
537 }
538}
539
540} // namespace amlogic
541} // namespace android
542