new_stream = kmemdup(stream, sizeof(struct dc_stream_state), GFP_KERNEL); if (!new_stream) return NULL;
if (new_stream->sink)
dc_sink_retain(new_stream->sink);
dc_stream_assign_stream_id(new_stream);
/* If using dynamic encoder assignment, wait till stream committed to assign encoder. */ if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign &&
!new_stream->ctx->dc->config.unify_link_enc_assignment)
new_stream->link_enc = NULL;
void program_cursor_attributes( struct dc *dc, struct dc_stream_state *stream)
{ int i; struct resource_context *res_ctx; struct pipe_ctx *pipe_to_program = NULL;
if (!stream) return;
res_ctx = &dc->current_state->res_ctx;
for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
if (pipe_ctx->stream != stream) continue;
if (!pipe_to_program) {
pipe_to_program = pipe_ctx;
dc->hwss.cursor_lock(dc, pipe_to_program, true); if (pipe_to_program->next_odm_pipe)
dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, true);
}
dc->hwss.set_cursor_attribute(pipe_ctx); if (dc->ctx->dmub_srv)
dc_send_update_cursor_info_to_dmu(pipe_ctx, i); if (dc->hwss.set_cursor_sdr_white_level)
dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
}
if (pipe_to_program) {
dc->hwss.cursor_lock(dc, pipe_to_program, false); if (pipe_to_program->next_odm_pipe)
dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, false);
}
}
if (NULL == stream) {
dm_error("DC: dc_stream is NULL!\n"); returnfalse;
} if (NULL == attributes) {
dm_error("DC: attributes is NULL!\n"); returnfalse;
}
if (attributes->address.quad_part == 0) {
dm_output_to_console("DC: Cursor address is 0!\n"); returnfalse;
}
dc = stream->ctx->dc;
/* SubVP is not compatible with HW cursor larger than what can fit in cursor SRAM. *Therefore,ifcursorisgreaterthanthis,fallbacktoSWcursor.
*/ if (dc->debug.allow_sw_cursor_fallback && dc->res_pool->funcs->get_max_hw_cursor_size) {
max_cursor_size = dc->res_pool->funcs->get_max_hw_cursor_size(dc, state, stream);
max_cursor_size = max_cursor_size * max_cursor_size * 4;
program_cursor_position(dc, stream); /* re-enable idle optimizations if necessary */ if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle)
dc_allow_idle_optimizations(dc, true);
/* apply/update visual confirm */ if (dc->debug.visual_confirm == VISUAL_CONFIRM_HW_CURSOR) { /* update software state */ int i;
for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
/* adjust visual confirm color for all pipes with current stream */ if (stream == pipe_ctx->stream) {
get_cursor_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
if (stream == NULL) {
dm_error("DC: dc_stream is NULL!\n"); returnfalse;
}
if (dwb_pipe_inst >= MAX_DWB_PIPES) {
dm_error("DC: writeback pipe is invalid!\n"); returnfalse;
}
if (stream->num_wb_info > MAX_DWB_PIPES) {
dm_error("DC: num_wb_info is invalid!\n"); returnfalse;
}
dc_exit_ips_for_hw_access(dc);
if (dwb->funcs->set_fc_enable)
dwb->funcs->set_fc_enable(dwb, DWB_FRAME_CAPTURE_DISABLE);
returntrue;
}
/** *dc_stream_remove_writeback()-Disableswritebackandremoveswritebackinfo. *@dc:Displaycorecontrolstructure. *@stream:Displaycorestreamstate. *@dwb_pipe_inst:Displaywritebackpipe. * *Return:returnstrueonsuccess,falseotherwise.
*/ bool dc_stream_remove_writeback(struct dc *dc, struct dc_stream_state *stream,
uint32_t dwb_pipe_inst)
{ unsignedint i, j; if (stream == NULL) {
dm_error("DC: dc_stream is NULL!\n"); returnfalse;
}
if (dwb_pipe_inst >= MAX_DWB_PIPES) {
dm_error("DC: writeback pipe is invalid!\n"); returnfalse;
}
if (stream->num_wb_info > MAX_DWB_PIPES) {
dm_error("DC: num_wb_info is invalid!\n"); returnfalse;
}
/* remove writeback info for disabled writeback pipes from stream */ for (i = 0, j = 0; i < stream->num_wb_info; i++) { if (stream->writeback_info[i].wb_enabled) {
if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst)
stream->writeback_info[i].wb_enabled = false;
/* trim the array */ if (j < i) {
memcpy(&stream->writeback_info[j], &stream->writeback_info[i], sizeof(struct dc_writeback_info));
j++;
}
}
}
stream->num_wb_info = j;
/* recalculate and apply DML parameters */ if (!dc->hwss.update_bandwidth(dc, dc->current_state)) {
dm_error("DC: update_bandwidth failed!\n"); returnfalse;
}
for (i = 0; i < MAX_PIPES; i++) { struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
if (res_ctx->pipe_ctx[i].stream != stream || !tg) continue;
return tg->funcs->get_frame_count(tg);
}
return0;
}
bool dc_stream_send_dp_sdp(conststruct dc_stream_state *stream, const uint8_t *custom_sdp_message, unsignedint sdp_message_size)
{ int i; struct dc *dc; struct resource_context *res_ctx;
if (stream == NULL) {
dm_error("DC: dc_stream is NULL!\n"); returnfalse;
}
dc = stream->ctx->dc;
res_ctx = &dc->current_state->res_ctx;
dc_exit_ips_for_hw_access(dc);
for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
if (pipe_ctx->stream != stream) continue;
if (dc->hwss.send_immediate_sdp_message != NULL)
dc->hwss.send_immediate_sdp_message(pipe_ctx,
custom_sdp_message,
sdp_message_size); else
DC_LOG_WARNING("%s:send_immediate_sdp_message not implemented on this ASIC\n",
__func__);
bool dc_stream_dmdata_status_done(struct dc *dc, struct dc_stream_state *stream)
{ struct pipe_ctx *pipe = NULL; int i;
if (!dc->hwss.dmdata_status_done) returnfalse;
for (i = 0; i < MAX_PIPES; i++) {
pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->stream == stream) break;
} /* Stream not found, by default we'll assume HUBP fetched dm data */ if (i == MAX_PIPES) returntrue;
// see if one is allocated for this stream for (int i = 0; i < num_rmcm; i++) { if (dc->res_pool->rmcm_3dlut[i].isInUse &&
dc->res_pool->rmcm_3dlut[i].stream == stream) return &dc->res_pool->rmcm_3dlut[i];
}
//case: not found one, and dont need to allocate if (!allocate_one) return NULL;
//see if there is an unused 3dlut, allocate for (int i = 0; i < num_rmcm; i++) { if (!dc->res_pool->rmcm_3dlut[i].isInUse) {
dc->res_pool->rmcm_3dlut[i].isInUse = true;
dc->res_pool->rmcm_3dlut[i].stream = stream; return &dc->res_pool->rmcm_3dlut[i];
}
}
/* *Findsthelowest/highestrefreshrate(dependingonsearch_for_max_increase) *thatcanbeachievedfromstarting_refresh_hzwhilestaying *withinflickercriteria
*/ staticint dc_stream_calculate_flickerless_refresh_rate(struct dc_stream_state *stream, int current_brightness, int starting_refresh_hz, bool is_gaming, bool search_for_max_increase)
{ int nearest_smallest_index = dc_stream_get_nearest_smallest_index(stream, starting_refresh_hz);
int flicker_criteria_millinits = is_gaming ?
stream->lumin_data.flicker_criteria_milli_nits_GAMING :
stream->lumin_data.flicker_criteria_milli_nits_STATIC;
int safe_upper_bound = current_brightness + flicker_criteria_millinits; int safe_lower_bound = current_brightness - flicker_criteria_millinits; int lumin_millinits_temp = 0;
int offset = -1; if (search_for_max_increase) {
offset = 1;
}
/* *Incrementsupordownby1dependingonsearch_for_max_increase
*/ for (int i = nearest_smallest_index; (i > 0 && !search_for_max_increase) || (i < (LUMINANCE_DATA_TABLE_SIZE - 1) && search_for_max_increase); i += offset) {
/* *Needthesecondinputtobe<thirdinputfordc_stream_get_refresh_hz_linear_interpolation
*/ if (search_for_max_increase)
refresh = dc_stream_get_refresh_hz_linear_interpolation(stream, i, i + offset, target_brightness); else
refresh = dc_stream_get_refresh_hz_linear_interpolation(stream, i + offset, i, target_brightness);
if (refresh == stream->lumin_data.refresh_rate_hz[i + offset]) return stream->lumin_data.refresh_rate_hz[i + offset];
return refresh;
}
}
if (search_for_max_increase) return (int)div64_s64((longlong)stream->timing.pix_clk_100hz*100, stream->timing.v_total*(longlong)stream->timing.h_total); else return stream->lumin_data.refresh_rate_hz[0];
}
/* *Getsthemaxdeltaluminancewithinaspecifiedrefreshrange
*/ staticint dc_stream_get_max_delta_lumin_millinits(struct dc_stream_state *stream, int hz1, int hz2, bool isGaming)
{ int lower_refresh_brightness = dc_stream_get_brightness_millinits_from_refresh (stream, hz1); int higher_refresh_brightness = dc_stream_get_brightness_millinits_from_refresh (stream, hz2);
int min = lower_refresh_brightness; int max = higher_refresh_brightness;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.