Skip to content
This repository has been archived by the owner on Oct 8, 2024. It is now read-only.

Correct the alpha logic in glProgram #580

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion common/compositor/compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,25 @@ static std::vector<size_t> SetBitsToVector(

void Compositor::SeparateLayers(const std::vector<size_t> &dedicated_layers,
const std::vector<size_t> &source_layers,
const std::vector<HwcRect<int>> &display_frame,
const std::vector<HwcRect<int>> &display_frames,
const HwcRect<int> &damage_region,
std::vector<CompositionRegion> &comp_regions) {
CTRACE();

#if 1
// we just need to return layers with damage region into com_regions
int index = 0;
while (index < source_layers.size()) {
CompositionRegion comp;
size_t layer_index = source_layers.at(index);
comp.frame = display_frames.at(layer_index);
comp.source_layers.emplace_back(layer_index);
index++;
comp_regions.emplace_back(comp);
}
#else
// legacy seprate layers logic

if (source_layers.size() > 64) {
ETRACE("Failed to separate layers because there are more than 64");
return;
Expand Down Expand Up @@ -381,6 +396,7 @@ void Compositor::SeparateLayers(const std::vector<size_t> &dedicated_layers,
region.rect, SetBitsToVector(region.id_set.getBits() >> layer_offset,
source_layers)});
}
#endif
}

} // namespace hwcomposer
30 changes: 17 additions & 13 deletions common/compositor/gl/egloffscreencontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,27 @@ bool EGLOffScreenContext::MakeCurrent() {
return true;
}

EGLint EGLOffScreenContext::GetSyncFD() {
EGLint EGLOffScreenContext::GetSyncFD(bool onScreen) {
EGLint sync_fd = -1;

EGLSyncKHR egl_sync =
eglCreateSyncKHR(egl_display_, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
if (egl_sync == EGL_NO_SYNC_KHR) {
ETRACE("Failed to make sync object.");
return -1;
}
if (onScreen)
glFlush();
else {
EGLSyncKHR egl_sync =
eglCreateSyncKHR(egl_display_, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
if (egl_sync == EGL_NO_SYNC_KHR) {
ETRACE("Failed to make sync object.");
return -1;
}

sync_fd = eglDupNativeFenceFDANDROID(egl_display_, egl_sync);
if (sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
ETRACE("Failed to duplicate native fence object.");
sync_fd = -1;
}
sync_fd = eglDupNativeFenceFDANDROID(egl_display_, egl_sync);
if (sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
ETRACE("Failed to duplicate native fence object.");
sync_fd = -1;
}

eglDestroySyncKHR(egl_display_, egl_sync);
eglDestroySyncKHR(egl_display_, egl_sync);
}

return sync_fd;
}
Expand Down
2 changes: 1 addition & 1 deletion common/compositor/gl/egloffscreencontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class EGLOffScreenContext {

bool Init();

EGLint GetSyncFD();
EGLint GetSyncFD(bool onScreen);

EGLDisplay GetDisplay() const {
return egl_display_;
Expand Down
113 changes: 47 additions & 66 deletions common/compositor/gl/glprogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,15 @@ static std::string GenerateVertexShader(int layer_count) {
<< "#define LAYER_COUNT " << layer_count << "\n"
<< "precision mediump int;\n"
<< "uniform vec4 uViewport;\n"
<< "uniform vec4 uLayerCrop[LAYER_COUNT];\n"
<< "uniform mat2 uTexMatrix[LAYER_COUNT];\n"
<< "uniform vec4 uLayerCrop;\n"
<< "uniform mat2 uTexMatrix;\n"
<< "in vec2 vPosition;\n"
<< "in vec2 vTexCoords;\n"
<< "out vec2 fTexCoords[LAYER_COUNT];\n"
<< "out vec2 fTexCoords;\n"
<< "void main() {\n"
<< " for (int i = 0; i < LAYER_COUNT; i++) {\n"
<< " vec2 tempCoords = vTexCoords * uTexMatrix[i];\n"
<< " fTexCoords[i] =\n"
<< " uLayerCrop[i].xy + tempCoords * uLayerCrop[i].zw;\n"
<< " }\n"
<< " vec2 tempCoords = vTexCoords * uTexMatrix;\n"
<< " fTexCoords =\n"
<< " uLayerCrop.xy + tempCoords * uLayerCrop.zw;\n"
<< " vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;\n"
<< " gl_Position =\n"
<< " vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);\n"
Expand All @@ -85,53 +83,39 @@ static std::string GenerateVertexShader(int layer_count) {

static std::string GenerateFragmentShader(int layer_count) {
std::ostringstream fragment_shader_stream;
fragment_shader_stream << "#version 300 es\n"
<< "#define LAYER_COUNT " << layer_count << "\n"
<< "#extension GL_OES_EGL_image_external : require\n"
<< "precision mediump float;\n";
for (int i = 0; i < layer_count; ++i) {
fragment_shader_stream << "uniform samplerExternalOES uLayerTexture" << i
<< ";\n";
}
fragment_shader_stream << "uniform float uLayerAlpha[LAYER_COUNT];\n"
<< "uniform float uLayerPremult[LAYER_COUNT];\n"
<< "uniform vec4 uLayerColor[LAYER_COUNT];\n"
<< "in vec2 fTexCoords[LAYER_COUNT];\n"
<< "out vec4 oFragColor;\n"
fragment_shader_stream
<< "#version 300 es\n"
<< "#define LAYER_COUNT " << 1 << "\n"
<< "#extension GL_OES_EGL_image_external : require\n"
<< "#extension GL_EXT_shader_framebuffer_fetch : require\n" 
<< "precision mediump float;\n";
fragment_shader_stream << "uniform samplerExternalOES uLayerTexture;\n";

fragment_shader_stream << "uniform float uLayerAlpha;\n"
<< "uniform float uLayerPremult;\n"
<< "uniform vec4 uLayerColor;\n"
<< "in vec2 fTexCoords;\n"
<< "inout vec4 oFragColor;\n"
<< "void main() {\n"
<< " vec3 color = vec3(0.0, 0.0, 0.0);\n"
<< " float alphaCover = 1.0;\n"
<< " vec3 color = oFragColor.rgb;\n"
<< " float alphaCover = 1.0 - oFragColor.a;\n"
<< " vec4 texSample;\n"
<< " vec3 multRgb;\n"
<< " float tempAlpha;\n";
for (int i = 0; i < layer_count; ++i) {
if (i > 0)
fragment_shader_stream << " if (alphaCover > 0.5/255.0) {\n";
// clang-format off
fragment_shader_stream << " texSample = texture2D(uLayerTexture" << i
<< ",\n"
<< " fTexCoords[" << i
<< "]);\n"
<< " texSample.rgb = texSample.rgb + uLayerColor[" << i
<< "].rgb;\n"
<< " tempAlpha = min(texSample.a, uLayerColor[" << i
<< "].a);\n"
<< " multRgb = texSample.rgb *\n"
<< " max(tempAlpha, uLayerPremult[" << i
<< "]);\n"
<< " color += multRgb * uLayerAlpha[" << i
<< "] * alphaCover;\n"
<< " alphaCover *= 1.0 - texSample.a * uLayerAlpha["
<< i << "];\n";
// clang-format on
}
for (int i = 0; i < layer_count - 1; ++i)
fragment_shader_stream << " }\n";
fragment_shader_stream << " oFragColor = vec4(color, 1.0 - alphaCover);\n"
<< "}\n";
<< " float tempAlpha;\n"
<< " if (alphaCover > 0.5/255.0) { \n";
// clang-format off
fragment_shader_stream << " texSample = texture2D(uLayerTexture, fTexCoords); \n"
<< " texSample.rgb = texSample.rgb + uLayerColor.rgb; \n"
<< " tempAlpha = min(texSample.a, uLayerColor.a); \n"
<< " multRgb = texSample.rgb *max(tempAlpha, uLayerPremult); \n"
<< " color += multRgb * uLayerAlpha * alphaCover; \n"
<< " alphaCover *= (1.0 - texSample.a * uLayerAlpha);\n"
<< " oFragColor = vec4(color, 1.0 - alphaCover);\n"
<< " }}\n";
return fragment_shader_stream.str();
}


#if defined(LOAD_PREBUILT_SHADER_FILE) || defined(USE_PREBUILT_SHADER_BIN_ARRAY)
static GLint LoadPreBuiltBinary(GLint gl_program, void *binary, long size) {
GLint status;
Expand Down Expand Up @@ -311,7 +295,7 @@ GLProgram::~GLProgram() {

bool GLProgram::Init(unsigned texture_count) {
std::ostringstream shader_log;
program_ = GenerateProgram(texture_count, &shader_log);
program_ = GenerateProgram(1, &shader_log);
if (!program_) {
ETRACE("%s", shader_log.str().c_str());
return false;
Expand All @@ -331,38 +315,35 @@ void GLProgram::UseProgram(const RenderState &state, GLuint viewport_width,
premult_loc_ = glGetUniformLocation(program_, "uLayerPremult");
tex_matrix_loc_ = glGetUniformLocation(program_, "uTexMatrix");
solid_color_loc_ = glGetUniformLocation(program_, "uLayerColor");
for (unsigned src_index = 0; src_index < size; src_index++) {
std::ostringstream texture_name_formatter;
texture_name_formatter << "uLayerTexture" << src_index;
GLuint tex_loc =
std::ostringstream texture_name_formatter;
texture_name_formatter << "uLayerTexture";
GLuint tex_loc =
glGetUniformLocation(program_, texture_name_formatter.str().c_str());
glUniform1i(tex_loc, src_index);
}
glUniform1i(tex_loc, 0);

initialized_ = true;
}

glUniform4f(viewport_loc_, state.x_ / (float)viewport_width,
glUniform4f(viewport_loc_, state.x_ / (float)viewport_width,
state.y_ / (float)viewport_height,
(state.width_) / (float)viewport_width,
(state.height_) / (float)viewport_height);

for (unsigned src_index = 0; src_index < size; src_index++) {
const RenderState::LayerState &src = state.layer_state_[src_index];
glUniform1f(alpha_loc_ + src_index, src.alpha_);
glUniform1f(premult_loc_ + src_index, src.premult_);
glUniform4f(crop_loc_ + src_index, src.crop_bounds_[0], src.crop_bounds_[1],
const RenderState::LayerState &src = state.layer_state_[0];
glUniform1f(alpha_loc_, src.alpha_);
glUniform1f(premult_loc_, src.premult_);
glUniform4f(crop_loc_, src.crop_bounds_[0], src.crop_bounds_[1],
src.crop_bounds_[2] - src.crop_bounds_[0],
src.crop_bounds_[3] - src.crop_bounds_[1]);
glUniformMatrix2fv(tex_matrix_loc_ + src_index, 1, GL_FALSE,
glUniformMatrix2fv(tex_matrix_loc_, 1, GL_FALSE,
src.texture_matrix_);
glActiveTexture(GL_TEXTURE0 + src_index);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, src.handle_);
glUniform4f(solid_color_loc_ + src_index, (float)src.solid_color_array_[3],
glUniform4f(solid_color_loc_, (float)src.solid_color_array_[3],
(float)src.solid_color_array_[2],
(float)src.solid_color_array_[1],
(float)src.solid_color_array_[0]);
}
}

} // namespace hwcomposer
15 changes: 11 additions & 4 deletions common/compositor/gl/glrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ bool GLRenderer::Draw(const std::vector<RenderState> &render_states,
surface->SetClearSurface(NativeSurface::kNone);

glViewport(left, top, frame_width, frame_height);
glClearColor(0.0, 0.0, 0.0, 0.0);

if (clear_surface || partial_clear) {
const HwcRect<int> &damage = surface->GetSurfaceDamage();
Expand All @@ -121,6 +122,7 @@ bool GLRenderer::Draw(const std::vector<RenderState> &render_states,
}
} else {
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
}

#ifdef COMPOSITOR_TRACING
Expand All @@ -135,19 +137,24 @@ bool GLRenderer::Draw(const std::vector<RenderState> &render_states,
damage.left, damage.top, damage.right - damage.left,
damage.bottom - damage.top);
#endif
for (const RenderState &state : render_states) {
int state_index = 0;
while (state_index < render_states.size()) {
const RenderState &state = render_states.at(state_index++);
unsigned size = state.layer_state_.size();
GLProgram *program = GetProgram(size);
ETRACE("renderstate layer size %d, layer index %d", size,
state.layer_state_[0].layer_index_);
GLProgram *program = GetProgram(1);
if (!program)
continue;

program->UseProgram(state, frame_width, frame_height);
#ifdef COMPOSITOR_TRACING
ICOMPOSITORTRACE(
ETRACE(
"scissor_x_: %d state.scissor_y_: %d scissor_width_: %d "
"scissor_height_: %d \n",
state.scissor_x_, state.scissor_y_, state.scissor_width_,
state.scissor_height_);

total_width += std::max(total_width, state.scissor_width_);
total_height += state.scissor_height_;
const HwcRect<int> &damage = surface->GetSurfaceDamage();
Expand All @@ -173,7 +180,7 @@ bool GLRenderer::Draw(const std::vector<RenderState> &render_states,
glDisable(GL_SCISSOR_TEST);

if (!disable_explicit_sync_)
surface->SetNativeFence(context_.GetSyncFD());
surface->SetNativeFence(context_.GetSyncFD(surface->IsOnScreen()));

surface->ResetDamage();
#ifdef COMPOSITOR_TRACING
Expand Down
13 changes: 12 additions & 1 deletion common/core/gpudevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ bool GpuDevice::Initialize() {
ETRACE("Failed to open %s", HWC_LOCK_FILE);
// HWC should become drm master and start to commit.
// if hwc.lock is not available
display_manager_->setDrmMaster(true);
if (!display_manager_->IsDrmMasterByDefault())
display_manager_->setDrmMaster(true);
ResetAllDisplayCommit(true);
}

Expand Down Expand Up @@ -129,6 +130,15 @@ bool GpuDevice::EnableDRMCommit(bool enable, uint32_t display_id) {
return ret;
}

void GpuDevice::MarkDisplayForFirstCommit() {
size_t size = total_displays_.size();
for (size_t i = 0; i < size; i++) {
if (total_displays_.at(i)->IsConnected()) {
total_displays_.at(i)->MarkFirstCommit();
}
}
}

bool GpuDevice::ResetDrmMaster(bool drop_master) {
bool ret = true;
if (drop_master) {
Expand All @@ -148,6 +158,7 @@ bool GpuDevice::ResetDrmMaster(bool drop_master) {
// In case of setDrmMaster or the lock file is not exist.
// Re-set DRM Master true.
display_manager_->setDrmMaster(false);
MarkDisplayForFirstCommit();
ResetAllDisplayCommit(true);
DisableWatch();

Expand Down
2 changes: 1 addition & 1 deletion common/core/overlaylayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ struct OverlayLayer {
uint8_t alpha_ = 0xff;
uint32_t dataspace_ = 0;

uint32_t solid_color_ = 0;
uint32_t solid_color_ = 255;

HwcRect<float> source_crop_;
HwcRect<int> display_frame_;
Expand Down
3 changes: 2 additions & 1 deletion common/display/displayplanemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,8 @@ bool DisplayPlaneManager::SquashPlanesAsNeeded(
const HwcRect<int> &display_frame = scanout_plane.GetDisplayFrame();
const HwcRect<int> &target_frame = last_plane.GetDisplayFrame();
if (!scanout_plane.IsCursorPlane() && !scanout_plane.IsVideoPlane() &&
(AnalyseOverlap(display_frame, target_frame) != kOutside)) {
((AnalyseOverlap(display_frame, target_frame) != kOutside) /*||
scanout_plane.NeedsOffScreenComposition()*/)) {
if (!ForceSeparatePlane(layers, last_plane, NULL)) {
ISURFACETRACE("Squasing planes. \n");
const std::vector<size_t> &new_layers = last_plane.GetSourceLayers();
Expand Down
17 changes: 15 additions & 2 deletions common/display/displayqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <hwcdefs.h>
#include <hwclayer.h>
#include <math.h>

#include <sys/time.h>
#include <vector>

#include "displayplanemanager.h"
Expand Down Expand Up @@ -639,6 +639,14 @@ void DisplayQueue::InitializeOverlayLayers(
}
}

void DisplayQueue::TraceFirstCommit() {
struct timeval te;
gettimeofday(&te, NULL); // get current time
long long milliseconds =
te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds
ITRACE("First frame is Committed at %lld.", milliseconds);
}

bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,
int32_t* retire_fence, bool* ignore_clone_update,
PixelUploaderCallback* call_back,
Expand Down Expand Up @@ -899,10 +907,15 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,

int32_t fence = 0;
bool fence_released = false;
if (!IsIgnoreUpdates())
if (!IsIgnoreUpdates()) {
composition_passed = display_->Commit(
current_composition_planes, previous_plane_state_, disable_explictsync,
kms_fence_, &fence, &fence_released);
if (first_commit_) {
TraceFirstCommit();
first_commit_ = false;
}
}

if (fence_released) {
kms_fence_ = 0;
Expand Down
Loading