external/drm_hwcomposer
Revision | 0ffec0758c907bf237c7978f31653a86d921165d (tree) |
---|---|
Zeit | 2017-09-22 18:16:23 |
Autor | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge remote-tracking branch 'chromium/master' into nougat-x86
@@ -379,6 +379,9 @@ int DrmDisplayComposition::Plan(SquashState *squash, | ||
379 | 379 | if (!i.plane()) |
380 | 380 | continue; |
381 | 381 | |
382 | + // make sure that source layers are ordered based on zorder | |
383 | + std::sort(i.source_layers().begin(), i.source_layers().end()); | |
384 | + | |
382 | 385 | std::vector<DrmPlane *> *container; |
383 | 386 | if (i.plane()->type() == DRM_PLANE_TYPE_PRIMARY) |
384 | 387 | container = primary_planes; |
@@ -22,6 +22,7 @@ | ||
22 | 22 | |
23 | 23 | #include <cinttypes> |
24 | 24 | #include <stdatomic.h> |
25 | +#include <drm/drm_fourcc.h> | |
25 | 26 | #include <xf86drm.h> |
26 | 27 | #include <xf86drmMode.h> |
27 | 28 |
@@ -199,6 +200,7 @@ int NvImporter::GrallocSetNvBuffer(buffer_handle_t handle, NvBuffer_t *buf) { | ||
199 | 200 | // static |
200 | 201 | std::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) { |
201 | 202 | std::unique_ptr<Planner> planner(new Planner); |
203 | + planner->AddStage<PlanStageNvLimits>(); | |
202 | 204 | planner->AddStage<PlanStageProtectedRotated>(); |
203 | 205 | planner->AddStage<PlanStageProtected>(); |
204 | 206 | planner->AddStage<PlanStagePrecomp>(); |
@@ -283,4 +285,90 @@ int PlanStageProtectedRotated::ProvisionPlanes( | ||
283 | 285 | } |
284 | 286 | return 0; |
285 | 287 | } |
288 | + | |
289 | +bool PlanStageNvLimits::CheckLayer(size_t zorder, DrmHwcLayer *layer) { | |
290 | + auto src_w = layer->source_crop.width(); | |
291 | + auto src_h = layer->source_crop.height(); | |
292 | + auto dst_w = layer->display_frame.width(); | |
293 | + auto dst_h = layer->display_frame.height(); | |
294 | + int h_limit = 4; | |
295 | + int v_limit; | |
296 | + | |
297 | + switch (layer->buffer->format) { | |
298 | + case DRM_FORMAT_ARGB8888: | |
299 | + case DRM_FORMAT_ABGR8888: | |
300 | + case DRM_FORMAT_XBGR8888: | |
301 | + case DRM_FORMAT_XRGB8888: | |
302 | + // tegra driver assumes any layer with alpha channel has premult | |
303 | + // blending, avoid handling it this is not the case. This is not an | |
304 | + // issue for bottom-most layer since there's nothing to blend with | |
305 | + if (zorder > 0 && layer->blending != DrmHwcBlending::kPreMult) | |
306 | + return false; | |
307 | + | |
308 | + v_limit = 2; | |
309 | + break; | |
310 | + case DRM_FORMAT_YVU420: | |
311 | + case DRM_FORMAT_YUV420: | |
312 | + case DRM_FORMAT_YUV422: | |
313 | + case DRM_FORMAT_UYVY: | |
314 | + case DRM_FORMAT_YUYV: | |
315 | + case DRM_FORMAT_NV12: | |
316 | + case DRM_FORMAT_NV21: | |
317 | + case DRM_FORMAT_RGB565: | |
318 | + case DRM_FORMAT_BGR565: | |
319 | + v_limit = 4; | |
320 | + break; | |
321 | + default: | |
322 | + v_limit = 2; | |
323 | + break; | |
324 | + } | |
325 | + | |
326 | + if (layer->transform & | |
327 | + (DrmHwcTransform::kRotate90 | DrmHwcTransform::kRotate270)) | |
328 | + std::swap(dst_w, dst_h); | |
329 | + | |
330 | + // check for max supported down scaling | |
331 | + if (((src_w / dst_w) > h_limit) || ((src_h / dst_h) > v_limit)) | |
332 | + return false; | |
333 | + | |
334 | + return true; | |
335 | +} | |
336 | + | |
337 | +int PlanStageNvLimits::ProvisionPlanes( | |
338 | + std::vector<DrmCompositionPlane> *composition, | |
339 | + std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, | |
340 | + std::vector<DrmPlane *> *planes) { | |
341 | + int ret; | |
342 | + | |
343 | + for (auto i = layers.begin(); i != layers.end();) { | |
344 | + // Skip layer if supported | |
345 | + if (CheckLayer(i->first, i->second)) { | |
346 | + i++; | |
347 | + continue; | |
348 | + } | |
349 | + | |
350 | + if (i->second->protected_usage()) { | |
351 | + // Drop the layer if unsupported and protected, this will just display | |
352 | + // black in the area of this layer but it's better than failing miserably | |
353 | + i = layers.erase(i); | |
354 | + continue; | |
355 | + } | |
356 | + | |
357 | + // If there's no precomp layer already queued, queue one now. | |
358 | + DrmCompositionPlane *precomp = GetPrecomp(composition); | |
359 | + if (precomp) { | |
360 | + precomp->source_layers().emplace_back(i->first); | |
361 | + } else if (!planes->empty()) { | |
362 | + DrmPlane *precomp_plane = planes->back(); | |
363 | + planes->pop_back(); | |
364 | + composition->emplace_back(DrmCompositionPlane::Type::kPrecomp, | |
365 | + precomp_plane, crtc, i->first); | |
366 | + } else { | |
367 | + ALOGE("Not enough planes to reserve for precomp fb"); | |
368 | + } | |
369 | + i = layers.erase(i); | |
370 | + } | |
371 | + | |
372 | + return 0; | |
373 | +} | |
286 | 374 | } |
@@ -72,6 +72,19 @@ class PlanStageProtectedRotated : public Planner::PlanStage { | ||
72 | 72 | std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, |
73 | 73 | std::vector<DrmPlane *> *planes); |
74 | 74 | }; |
75 | + | |
76 | +// This stage looks for layers that would not be supported by Tegra driver due | |
77 | +// to limitations such as downscaling. If the layer is unprotected it will be | |
78 | +// punted for precomp to handle, other wise if protected it will be dropped as | |
79 | +// it cannot be supported by any means. | |
80 | +class PlanStageNvLimits : public Planner::PlanStage { | |
81 | + public: | |
82 | + int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition, | |
83 | + std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, | |
84 | + std::vector<DrmPlane *> *planes); | |
85 | + protected: | |
86 | + bool CheckLayer(size_t zorder, DrmHwcLayer *layer); | |
87 | +}; | |
75 | 88 | } |
76 | 89 | |
77 | 90 | #endif |