Back to index

unity  6.0.0
OverlayRenderer.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2011 Canonical Ltd
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 3 as
00007  * published by the Free Software Foundation.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Authored by: Gordon Allott <gord.allott@canonical.com>
00018  */
00019 
00020 
00021 #include "OverlayRenderer.h"
00022 
00023 #include <NuxGraphics/GraphicsEngine.h>
00024 #include <Nux/PaintLayer.h>
00025 #include <NuxCore/Logger.h>
00026 
00027 #include "unity-shared/BackgroundEffectHelper.h"
00028 #include "DashStyle.h"
00029 #include "unity-shared/UnitySettings.h"
00030 
00031 #include "unity-shared/UBusMessages.h"
00032 #include "unity-shared/UBusWrapper.h"
00033 
00034 namespace unity
00035 {
00036 namespace
00037 {
00038 nux::logging::Logger logger("unity.overlayrenderer");
00039 
00040 const int INNER_CORNER_RADIUS = 5;
00041 const int EXCESS_BORDER = 10;
00042 }
00043 
00044 // Impl class
00045 class OverlayRendererImpl
00046 {
00047 public:
00048   OverlayRendererImpl(OverlayRenderer *parent_);
00049   ~OverlayRendererImpl();
00050 
00051   void Init();
00052   void OnBackgroundColorChanged(GVariant* args);
00053 
00054   void Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_draw);
00055   void DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry);
00056   void DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry);
00057 
00058   BackgroundEffectHelper bg_effect_helper_;
00059   nux::ColorLayer* bg_layer_;
00060   nux::ColorLayer* bg_darken_layer_;
00061   nux::Color bg_color_;
00062 
00063   nux::Geometry content_geo;
00064   nux::ObjectPtr <nux::IOpenGLBaseTexture> bg_blur_texture_;
00065   nux::ObjectPtr <nux::IOpenGLBaseTexture> bg_shine_texture_;
00066 
00067   // temporary variable that stores the number of backgrounds we have rendered
00068   int bgs;
00069   bool visible;
00070 
00071   UBusManager ubus_manager_;
00072 
00073   OverlayRenderer *parent;
00074 
00075   void InitASMInverseTextureMaskShader();
00076   void InitSlInverseTextureMaskShader();
00077 
00078   nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> inverse_texture_mask_asm_prog_;
00079   nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> inverse_texture_rect_mask_asm_prog_;
00080   nux::ObjectPtr<nux::IOpenGLShaderProgram> inverse_texture_mask_prog_;
00081 
00082   void RenderInverseMask_GLSL(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0);
00083   void RenderInverseMask_ASM(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0);
00084   void RenderInverseMask(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0);
00085 
00086 };
00087 
00088 OverlayRendererImpl::OverlayRendererImpl(OverlayRenderer *parent_)
00089   : visible(false)
00090   , parent(parent_)
00091 {
00092   bg_effect_helper_.enabled = false;
00093   Init();
00094 }
00095 
00096 OverlayRendererImpl::~OverlayRendererImpl()
00097 {
00098   delete bg_layer_;
00099   delete bg_darken_layer_;
00100 }
00101 
00102 void OverlayRendererImpl::Init()
00103 {
00104   nux::ROPConfig rop;
00105   rop.Blend = true;
00106   rop.SrcBlend = GL_ONE;
00107   rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
00108   bg_layer_ = new nux::ColorLayer(nux::Color(0.0f, 0.0f, 0.0f, 0.9), true, rop);
00109 
00110   rop.Blend = true;
00111   rop.SrcBlend = GL_ZERO;
00112   rop.DstBlend = GL_SRC_COLOR;
00113   bg_darken_layer_ = new nux::ColorLayer(nux::Color(0.9f, 0.9f, 0.9f, 1.0f), false, rop);
00114   bg_shine_texture_ = unity::dash::Style::Instance().GetDashShine()->GetDeviceTexture();
00115 
00116   ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED,
00117                                  sigc::mem_fun(this, &OverlayRendererImpl::OnBackgroundColorChanged));
00118 
00119   ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
00120 }
00121 
00122 void OverlayRendererImpl::OnBackgroundColorChanged(GVariant* args)
00123 {
00124   gdouble red, green, blue, alpha;
00125   g_variant_get (args, "(dddd)", &red, &green, &blue, &alpha);
00126 
00127   nux::Color color = nux::Color(red, green, blue, alpha);
00128   bg_layer_->SetColor(color);
00129   bg_color_ = color;
00130 
00131   parent->need_redraw.emit();
00132 }
00133 
00134 void OverlayRendererImpl::InitASMInverseTextureMaskShader()
00135 {
00136   nux::NString AsmVtx = 
00137       "!!ARBvp1.0                                 \n\
00138       ATTRIB iPos         = vertex.position;      \n\
00139       ATTRIB iColor       = vertex.attrib[3];     \n\
00140       PARAM  mvp[4]       = {state.matrix.mvp};   \n\
00141       OUTPUT oPos         = result.position;      \n\
00142       OUTPUT oColor       = result.color;         \n\
00143       OUTPUT oTexCoord0   = result.texcoord[0];   \n\
00144       # Transform the vertex to clip coordinates. \n\
00145       DP4   oPos.x, mvp[0], iPos;                     \n\
00146       DP4   oPos.y, mvp[1], iPos;                     \n\
00147       DP4   oPos.z, mvp[2], iPos;                     \n\
00148       DP4   oPos.w, mvp[3], iPos;                     \n\
00149       MOV   oColor, iColor;                           \n\
00150       MOV   oTexCoord0, vertex.attrib[8];             \n\
00151       END";
00152 
00153   nux::NString AsmFrg = 
00154       "!!ARBfp1.0                                       \n\
00155       TEMP tex0;                                        \n\
00156       TEMP temp0;                                       \n\
00157       TEX tex0, fragment.texcoord[0], texture[0], 2D;   \n\
00158       MUL temp0, fragment.color, tex0;                  \n\
00159       SUB result.color, {1.0, 1.0, 1.0, 1.0}, temp0.aaaa;\n\
00160       END";
00161 
00162   nux::NString AsmFrgRect = 
00163     "!!ARBfp1.0                                         \n\
00164     TEMP tex0;                                          \n\
00165     TEMP temp0;                                         \n\
00166     TEX tex0, fragment.texcoord[0], texture[0], RECT;   \n\
00167     MUL temp0, fragment.color, tex0;                    \n\
00168     SUB result.color, {1.0, 1.0, 1.0, 1.0}, temp0.aaaa;  \n\
00169     END";
00170 
00171   inverse_texture_mask_asm_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram();
00172   inverse_texture_mask_asm_prog_->LoadVertexShader(AsmVtx.GetTCharPtr());
00173   inverse_texture_mask_asm_prog_->LoadPixelShader(AsmFrg.GetTCharPtr());
00174   inverse_texture_mask_asm_prog_->Link();
00175 
00176   inverse_texture_rect_mask_asm_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram();
00177   inverse_texture_rect_mask_asm_prog_->LoadVertexShader(AsmVtx.GetTCharPtr());
00178   inverse_texture_rect_mask_asm_prog_->LoadPixelShader(AsmFrgRect.GetTCharPtr());
00179   inverse_texture_rect_mask_asm_prog_->Link();
00180 }
00181 
00182 void OverlayRendererImpl::RenderInverseMask_ASM(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture, nux::TexCoordXForm &texxform, const nux::Color &color)
00183 {
00184 #ifndef NUX_OPENGLES_20
00185   if (!inverse_texture_mask_asm_prog_.IsValid() || !inverse_texture_rect_mask_asm_prog_.IsValid())
00186   {
00187     InitASMInverseTextureMaskShader();
00188   }
00189 
00190   QRP_Compute_Texture_Coord(width, height, device_texture, texxform);
00191   float fx = x, fy = y;
00192   float VtxBuffer[] =
00193   {
00194     fx,          fy,          0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha,
00195     fx,          fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha,
00196     fx + width,  fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha,
00197     fx + width,  fy,          0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha,
00198   };
00199 
00200   CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0));
00201   CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
00202   
00203   nux::ObjectPtr<nux::IOpenGLAsmShaderProgram> shader_program = inverse_texture_mask_asm_prog_;
00204   if (device_texture->Type().IsDerivedFromType(nux::IOpenGLRectangleTexture::StaticObjectType))
00205   {
00206     shader_program = inverse_texture_rect_mask_asm_prog_;
00207   }
00208   shader_program->Begin();
00209 
00210   gfx_context.SetTexture(GL_TEXTURE0, device_texture);
00211 
00212   CHECKGL(glMatrixMode(GL_MODELVIEW));
00213   CHECKGL(glLoadIdentity());
00214   CHECKGL(glLoadMatrixf((FLOAT *) gfx_context.GetOpenGLModelViewMatrix().m));
00215   CHECKGL(glMatrixMode(GL_PROJECTION));
00216   CHECKGL(glLoadIdentity());
00217   CHECKGL(glLoadMatrixf((FLOAT *) gfx_context.GetOpenGLProjectionMatrix().m));
00218 
00219 
00220   int VertexLocation          = nux::VTXATTRIB_POSITION;
00221   int TextureCoord0Location   = nux::VTXATTRIB_TEXCOORD0;
00222   int VertexColorLocation     = nux::VTXATTRIB_COLOR;
00223 
00224   CHECKGL(glEnableVertexAttribArrayARB(VertexLocation));
00225   CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer));
00226 
00227   if (TextureCoord0Location != -1)
00228   {
00229     CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location));
00230     CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4));
00231   }
00232 
00233   if (VertexColorLocation != -1)
00234   {
00235     CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation));
00236     CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8));
00237   }
00238 
00239   CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
00240 
00241   CHECKGL(glDisableVertexAttribArrayARB(VertexLocation));
00242 
00243   if (TextureCoord0Location != -1)
00244     CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location));
00245 
00246   if (VertexColorLocation != -1)
00247     CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation));
00248 
00249   shader_program->End();
00250 #endif
00251 }
00252 
00253 void OverlayRendererImpl::InitSlInverseTextureMaskShader()
00254 {
00255   nux::ObjectPtr<nux::IOpenGLVertexShader> VS = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader();
00256   nux::ObjectPtr<nux::IOpenGLPixelShader> PS = nux::GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader();
00257   nux::NString VSString;
00258   nux::NString PSString;
00259 
00260   VSString =  
00261              NUX_VERTEX_SHADER_HEADER
00262              "attribute vec4 AVertex;                                \n\
00263              attribute vec4 MyTextureCoord0;                         \n\
00264              attribute vec4 VertexColor;                             \n\
00265              uniform mat4 ViewProjectionMatrix;                      \n\
00266              varying vec4 varyTexCoord0;                             \n\
00267              varying vec4 varyVertexColor;                           \n\
00268              void main()                                             \n\
00269              {                                                       \n\
00270                gl_Position =  ViewProjectionMatrix * (AVertex);      \n\
00271                varyTexCoord0 = MyTextureCoord0;                      \n\
00272                varyVertexColor = VertexColor;                        \n\
00273              }";
00274 
00275   PSString =  
00276             NUX_FRAGMENT_SHADER_HEADER
00277              "varying vec4 varyTexCoord0;                               \n\
00278              varying vec4 varyVertexColor;                              \n\
00279              uniform sampler2D TextureObject0;                          \n\
00280              void main()                                                \n\
00281              {                                                          \n\
00282                vec4 v = varyVertexColor*texture2D(TextureObject0, varyTexCoord0.xy);       \n\
00283                gl_FragColor = vec4(1.0-v.a);                            \n\
00284              }";
00285 
00286   // Textured 2D Primitive Shader
00287   inverse_texture_mask_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram();
00288   VS->SetShaderCode(TCHAR_TO_ANSI(*VSString));
00289   PS->SetShaderCode(TCHAR_TO_ANSI(*PSString), "#define SAMPLERTEX2D");
00290 
00291   inverse_texture_mask_prog_->ClearShaderObjects();
00292   inverse_texture_mask_prog_->AddShaderObject(VS);
00293   inverse_texture_mask_prog_->AddShaderObject(PS);
00294   CHECKGL(glBindAttribLocation(inverse_texture_mask_prog_->GetOpenGLID(), 0, "AVertex"));
00295   inverse_texture_mask_prog_->Link();
00296 }
00297 
00298 void OverlayRendererImpl::RenderInverseMask_GLSL(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0)
00299 {
00300   if (!inverse_texture_mask_prog_.IsValid())
00301     InitSlInverseTextureMaskShader();
00302 
00303   QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform0);
00304   float fx = x, fy = y;
00305   float VtxBuffer[] =
00306   {
00307     fx,          fy,          0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha,
00308     fx,          fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha,
00309     fx + width,  fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha,
00310     fx + width,  fy,          0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha,
00311   };
00312 
00313   nux::ObjectPtr<nux::IOpenGLShaderProgram> ShaderProg;
00314 
00315   if (DeviceTexture->Type().IsDerivedFromType(nux::IOpenGLTexture2D::StaticObjectType))
00316   {
00317     ShaderProg = inverse_texture_mask_prog_;
00318   }
00319 
00320   CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0));
00321   CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
00322   ShaderProg->Begin();
00323 
00324   int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0");
00325   int VertexLocation = ShaderProg->GetAttributeLocation("AVertex");
00326   int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0");
00327   int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor");
00328 
00329   gfx_context.SetTexture(GL_TEXTURE0, DeviceTexture);
00330   CHECKGL(glUniform1iARB(TextureObjectLocation, 0));
00331 
00332   int     VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix");
00333   nux::Matrix4 MVPMatrix = gfx_context.GetOpenGLModelViewProjectionMatrix();
00334   ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m));
00335 
00336   CHECKGL(glEnableVertexAttribArrayARB(VertexLocation));
00337   CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer));
00338 
00339   if (TextureCoord0Location != -1)
00340   {
00341     CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location));
00342     CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4));
00343   }
00344 
00345   if (VertexColorLocation != -1)
00346   {
00347     CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation));
00348     CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8));
00349   }
00350 
00351   CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
00352 
00353   CHECKGL(glDisableVertexAttribArrayARB(VertexLocation));
00354 
00355   if (TextureCoord0Location != -1)
00356     CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location));
00357 
00358   if (VertexColorLocation != -1)
00359     CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation));
00360 
00361   ShaderProg->End();
00362 }
00363 
00364 void OverlayRendererImpl::RenderInverseMask(nux::GraphicsEngine& gfx_context, int x, int y, int width, int height, nux::ObjectPtr<nux::IOpenGLBaseTexture> DeviceTexture, nux::TexCoordXForm &texxform0, const nux::Color &color0)
00365 {
00366   if (nux::GetWindowThread()->GetGraphicsEngine().UsingGLSLCodePath())
00367   {
00368     RenderInverseMask_GLSL(gfx_context, x, y, width, height, DeviceTexture, texxform0, color0);
00369   }
00370   else
00371   {
00372     RenderInverseMask_ASM(gfx_context, x, y, width, height, DeviceTexture, texxform0, color0); 
00373   }
00374 }
00375 
00376 void OverlayRendererImpl::Draw(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry, bool force_edges)
00377 {
00378   bool paint_blur = BackgroundEffectHelper::blur_type != BLUR_NONE;
00379   nux::Geometry geo(content_geo);
00380 
00381   int excess_border = (Settings::Instance().GetFormFactor() != FormFactor::NETBOOK || force_edges) ? EXCESS_BORDER : 0;
00382 
00383   nux::Geometry larger_content_geo = content_geo;
00384   larger_content_geo.OffsetSize(excess_border, excess_border);
00385 
00386   nux::Geometry larger_geo(larger_content_geo);
00387 
00388   nux::Geometry larger_absolute_geo = absolute_geo;
00389   larger_absolute_geo.OffsetSize(excess_border, excess_border);
00390 
00391   nux::TexCoordXForm texxform_absolute_bg;
00392   texxform_absolute_bg.flip_v_coord = true;
00393   texxform_absolute_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00394   texxform_absolute_bg.uoffset = ((float) larger_content_geo.x) / larger_absolute_geo.width;
00395   texxform_absolute_bg.voffset = ((float) larger_content_geo.y) / larger_absolute_geo.height;
00396   texxform_absolute_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
00397 
00398   nux::Geometry blur_geo(larger_absolute_geo.x, larger_absolute_geo.y, larger_content_geo.width, larger_content_geo.height);
00399   if (paint_blur)
00400   {
00401     bg_blur_texture_ = bg_effect_helper_.GetBlurRegion(blur_geo);
00402   }
00403   else
00404   {
00405     bg_blur_texture_ = bg_effect_helper_.GetRegion(blur_geo); 
00406   }
00407 
00408   if (bg_blur_texture_.IsValid())
00409   {
00410     nux::Geometry bg_clip = larger_geo;
00411     gfx_context.PushClippingRectangle(bg_clip);
00412 
00413     gfx_context.GetRenderStates().SetBlend(false);
00414 #ifndef NUX_OPENGLES_20
00415     if (gfx_context.UsingGLSLCodePath())
00416       gfx_context.QRP_GLSL_ColorBlendOverTex (larger_content_geo.x, larger_content_geo.y,
00417                                            larger_content_geo.width, larger_content_geo.height,
00418                                            bg_blur_texture_, texxform_absolute_bg, nux::color::White,
00419                                            bg_color_, nux::LAYER_BLEND_MODE_OVERLAY);
00420 
00421     else
00422       gfx_context.QRP_1Tex (larger_content_geo.x, larger_content_geo.y,
00423                             larger_content_geo.width, larger_content_geo.height,
00424                             bg_blur_texture_, texxform_absolute_bg, nux::color::White);
00425 #else
00426       gfx_context.QRP_GLSL_ColorBlendOverTex (larger_content_geo.x, larger_content_geo.y,
00427                                       larger_content_geo.width, larger_content_geo.height,
00428                                       bg_blur_texture_, texxform_absolute_bg, nux::color::White,
00429                                       bg_color_, nux::LAYER_BLEND_MODE_OVERLAY);
00430 
00431 #endif
00432     gPainter.PopBackground();
00433 
00434     gfx_context.PopClippingRectangle();
00435   }
00436 
00437   // Draw the left and top lines
00438   dash::Style& style = dash::Style::Instance();
00439 
00440   gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00441   gfx_context.GetRenderStates().SetBlend(true);
00442   gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00443 
00444   const double line_opacity = 0.1f;
00445   const int gradient_width = 130;
00446   const int gradient_height = 50;
00447   const int horizontal_padding = 40;
00448   const int vertical_padding = 20;
00449 
00450   // Now that we mask the corners of the dash,
00451   // draw longer lines to fill the minimal gaps
00452   const int corner_overlap = 3;
00453 
00454   nux::Color line_color = nux::color::White * line_opacity;
00455 
00456   // Vertical lancher/dash separator
00457   nux::GetPainter().Paint2DQuadColor(gfx_context,
00458                                      nux::Geometry(geometry.x,
00459                                                    geometry.y + vertical_padding,
00460                                                    style.GetVSeparatorSize(),
00461                                                    gradient_height),
00462                                      nux::color::Transparent,
00463                                      line_color * 0.7f, // less opacity
00464                                      line_color * 0.7f, // less opacity
00465                                      nux::color::Transparent);
00466   nux::GetPainter().Draw2DLine(gfx_context,
00467                                geometry.x,
00468                                geometry.y + vertical_padding + gradient_height,
00469                                style.GetVSeparatorSize(),
00470                                geometry.y + content_geo.height + INNER_CORNER_RADIUS + corner_overlap,
00471                                line_color * 0.7f); // less opacity
00472 
00473   // Horizontal panel/dash separator
00474   nux::GetPainter().Paint2DQuadColor(gfx_context,
00475                                      nux::Geometry(geometry.x + horizontal_padding,
00476                                                    geometry.y,
00477                                                    gradient_width,
00478                                                    style.GetHSeparatorSize()),
00479                                      nux::color::Transparent,
00480                                      nux::color::Transparent,
00481                                      line_color,
00482                                      line_color);
00483   nux::GetPainter().Draw2DLine(gfx_context,
00484                                geometry.x + horizontal_padding + gradient_width,
00485                                geometry.y,
00486                                geometry.x + content_geo.width + INNER_CORNER_RADIUS + corner_overlap,
00487                                style.GetHSeparatorSize(),
00488                                line_color);
00489 
00490   // Draw the background
00491   bg_darken_layer_->SetGeometry(larger_content_geo);
00492   nux::GetPainter().RenderSinglePaintLayer(gfx_context, larger_content_geo, bg_darken_layer_);
00493 
00494 #ifndef NUX_OPENGLES_20
00495   if (gfx_context.UsingGLSLCodePath() == false)
00496   {
00497     bg_layer_->SetGeometry(larger_content_geo);
00498     nux::GetPainter().RenderSinglePaintLayer(gfx_context, larger_content_geo, bg_layer_);
00499   }
00500 #endif
00501 
00502   texxform_absolute_bg.flip_v_coord = false;
00503   texxform_absolute_bg.uoffset = (1.0f / bg_shine_texture_->GetWidth()) * parent->x_offset;
00504   texxform_absolute_bg.voffset = (1.0f / bg_shine_texture_->GetHeight()) * parent->y_offset;
00505 
00506   gfx_context.GetRenderStates().SetColorMask(true, true, true, false);
00507   gfx_context.GetRenderStates().SetBlend(true, GL_DST_COLOR, GL_ONE);
00508 
00509   gfx_context.QRP_1Tex (larger_content_geo.x, larger_content_geo.y,
00510                         larger_content_geo.width, larger_content_geo.height,
00511                         bg_shine_texture_, texxform_absolute_bg, nux::color::White);
00512 
00513   if (Settings::Instance().GetFormFactor() != FormFactor::NETBOOK || force_edges)
00514   {
00515     // Paint the edges
00516     {
00517       gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00518       gfx_context.GetRenderStates().SetBlend(true);
00519       gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00520 
00521       dash::Style& style = dash::Style::Instance();
00522       nux::BaseTexture* bottom = style.GetDashBottomTile();
00523       nux::BaseTexture* bottom_mask = style.GetDashBottomTileMask();
00524       nux::BaseTexture* right = style.GetDashRightTile();
00525       nux::BaseTexture* right_mask = style.GetDashRightTileMask();
00526       nux::BaseTexture* corner = style.GetDashCorner();
00527       nux::BaseTexture* corner_mask = style.GetDashCornerMask();
00528       nux::BaseTexture* left_corner = style.GetDashLeftCorner();
00529       nux::BaseTexture* left_corner_mask = style.GetDashLeftCornerMask();
00530       nux::BaseTexture* left_tile = style.GetDashLeftTile();
00531       nux::BaseTexture* top_corner = style.GetDashTopCorner();
00532       nux::BaseTexture* top_corner_mask = style.GetDashTopCornerMask();
00533       nux::BaseTexture* top_tile = style.GetDashTopTile();
00534       nux::TexCoordXForm texxform;
00535 
00536       int left_corner_offset = 10;
00537       int top_corner_offset = 10;
00538 
00539       geo.width += corner->GetWidth() - 10;
00540       geo.height += corner->GetHeight() - 10;
00541       {
00542         // Corner
00543         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00544         texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER);
00545 
00546         // Selectively erase blur region in the curbe
00547         gfx_context.QRP_ColorModTexAlpha(geo.x + (geo.width - corner->GetWidth()),
00548                                          geo.y + (geo.height - corner->GetHeight()),
00549                                          corner->GetWidth(),
00550                                          corner->GetHeight(),                                         
00551                                          corner_mask->GetDeviceTexture(),
00552                                          texxform,
00553                                          nux::color::Black);
00554 
00555         // Write correct alpha
00556         gfx_context.GetRenderStates().SetBlend(false);
00557         gfx_context.GetRenderStates().SetColorMask(false, false, false, true);
00558         RenderInverseMask(gfx_context, geo.x + (geo.width - corner->GetWidth()),
00559                              geo.y + (geo.height - corner->GetHeight()),
00560                              corner->GetWidth(),
00561                              corner->GetHeight(),
00562                              corner_mask->GetDeviceTexture(),
00563                              texxform,
00564                              nux::color::White);
00565 
00566         gfx_context.GetRenderStates().SetBlend(true);
00567         gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00568         gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00569 
00570         gfx_context.QRP_1Tex(geo.x + (geo.width - corner->GetWidth()),
00571                              geo.y + (geo.height - corner->GetHeight()),
00572                              corner->GetWidth(),
00573                              corner->GetHeight(),
00574                              corner->GetDeviceTexture(),
00575                              texxform,
00576                              nux::color::White);
00577       }
00578       {
00579         // Bottom repeated texture
00580         int real_width = geo.width - (left_corner->GetWidth() - left_corner_offset) - corner->GetWidth();
00581         int offset = real_width % bottom->GetWidth();
00582 
00583         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00584         texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
00585 
00586         // Selectively erase blur region in the curbe
00587         gfx_context.QRP_ColorModTexAlpha(left_corner->GetWidth() - left_corner_offset - offset,
00588                                          geo.y + (geo.height - bottom->GetHeight()),
00589                                          real_width + offset,
00590                                          bottom->GetHeight(),                                         
00591                                          bottom_mask->GetDeviceTexture(),
00592                                          texxform,
00593                                          nux::color::Black);
00594 
00595         // Write correct alpha
00596         gfx_context.GetRenderStates().SetBlend(false);
00597         gfx_context.GetRenderStates().SetColorMask(false, false, false, true);
00598         RenderInverseMask(gfx_context, left_corner->GetWidth() - left_corner_offset - offset,
00599                              geo.y + (geo.height - bottom->GetHeight()),
00600                              real_width + offset,
00601                              bottom->GetHeight(),
00602                              bottom_mask->GetDeviceTexture(),
00603                              texxform,
00604                              nux::color::White);
00605 
00606         gfx_context.GetRenderStates().SetBlend(true);
00607         gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00608         gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00609 
00610         gfx_context.QRP_1Tex(left_corner->GetWidth() - left_corner_offset - offset,
00611                              geo.y + (geo.height - bottom->GetHeight()),
00612                              real_width + offset,
00613                              bottom->GetHeight(),
00614                              bottom->GetDeviceTexture(),
00615                              texxform,
00616                              nux::color::White);
00617       }
00618       {
00619         // Bottom left corner
00620         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00621         texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER);
00622 
00623         // Selectively erase blur region in the curbe
00624         gfx_context.QRP_ColorModTexAlpha(geo.x - left_corner_offset,
00625                                          geo.y + (geo.height - left_corner->GetHeight()),
00626                                          left_corner->GetWidth(),
00627                                          left_corner->GetHeight(),                                         
00628                                          left_corner_mask->GetDeviceTexture(),
00629                                          texxform,
00630                                          nux::color::Black);
00631 
00632         // Write correct alpha
00633         gfx_context.GetRenderStates().SetBlend(false);
00634         gfx_context.GetRenderStates().SetColorMask(false, false, false, true);
00635         RenderInverseMask(gfx_context, geo.x - left_corner_offset,
00636                              geo.y + (geo.height - left_corner->GetHeight()),
00637                              left_corner->GetWidth(),
00638                              left_corner->GetHeight(),
00639                              left_corner_mask->GetDeviceTexture(),
00640                              texxform,
00641                              nux::color::White);
00642 
00643         gfx_context.GetRenderStates().SetBlend(true);
00644         gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00645         gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00646 
00647         gfx_context.QRP_1Tex(geo.x - left_corner_offset,
00648                              geo.y + (geo.height - left_corner->GetHeight()),
00649                              left_corner->GetWidth(),
00650                              left_corner->GetHeight(),
00651                              left_corner->GetDeviceTexture(),
00652                              texxform,
00653                              nux::color::White);
00654       }
00655       {
00656         // Left repeated texture
00657         nux::Geometry real_geo = geometry;
00658         int real_height = real_geo.height - geo.height;
00659         int offset = real_height % left_tile->GetHeight();
00660 
00661         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00662         texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
00663 
00664         gfx_context.QRP_1Tex(geo.x - 10,
00665                              geo.y + geo.height,
00666                              left_tile->GetWidth(),
00667                              real_height + offset,
00668                              left_tile->GetDeviceTexture(),
00669                              texxform,
00670                              nux::color::White);
00671       }
00672       {
00673         // Right edge
00674         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00675         texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
00676 
00677         // Selectively erase blur region in the curbe
00678         gfx_context.QRP_ColorModTexAlpha(geo.x + geo.width - right->GetWidth(),
00679                                          geo.y + top_corner->GetHeight() - top_corner_offset,
00680                                          right->GetWidth(),
00681                                          geo.height - corner->GetHeight() - (top_corner->GetHeight() - top_corner_offset),                                       
00682                                          right_mask->GetDeviceTexture(),
00683                                          texxform,
00684                                          nux::color::Black);
00685 
00686         // Write correct alpha
00687         gfx_context.GetRenderStates().SetBlend(false);
00688         gfx_context.GetRenderStates().SetColorMask(false, false, false, true);
00689         RenderInverseMask(gfx_context, geo.x + geo.width - right->GetWidth(),
00690                              geo.y + top_corner->GetHeight() - top_corner_offset,
00691                              right->GetWidth(),
00692                              geo.height - corner->GetHeight() - (top_corner->GetHeight() - top_corner_offset),
00693                              right_mask->GetDeviceTexture(),
00694                              texxform,
00695                              nux::color::White);
00696 
00697         gfx_context.GetRenderStates().SetBlend(true);
00698         gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00699         gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00700 
00701         gfx_context.QRP_1Tex(geo.x + geo.width - right->GetWidth(),
00702                              geo.y + top_corner->GetHeight() - top_corner_offset,
00703                              right->GetWidth(),
00704                              geo.height - corner->GetHeight() - (top_corner->GetHeight() - top_corner_offset),
00705                              right->GetDeviceTexture(),
00706                              texxform,
00707                              nux::color::White);
00708       }
00709       {
00710         // Top right corner
00711         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00712         texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER);
00713 
00714         // Selectively erase blur region in the curbe
00715         gfx_context.QRP_ColorModTexAlpha(geo.x + geo.width - right->GetWidth(),
00716                                         geo.y - top_corner_offset,
00717                                         top_corner->GetWidth(),
00718                                         top_corner->GetHeight(),
00719                                         top_corner_mask->GetDeviceTexture(),
00720                                         texxform,
00721                                         nux::color::Black);
00722 
00723         // Write correct alpha
00724         gfx_context.GetRenderStates().SetBlend(false);
00725         gfx_context.GetRenderStates().SetColorMask(false, false, false, true);
00726         RenderInverseMask(gfx_context, geo.x + geo.width - right->GetWidth(),
00727                                         geo.y - top_corner_offset,
00728                                         top_corner->GetWidth(),
00729                                         top_corner->GetHeight(),
00730                                         top_corner_mask->GetDeviceTexture(),
00731                                         texxform,
00732                                         nux::color::White);
00733 
00734         gfx_context.GetRenderStates().SetBlend(true);
00735         gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00736         gfx_context.GetRenderStates().SetColorMask(true, true, true, true);
00737         gfx_context.QRP_1Tex(geo.x + geo.width - right->GetWidth(),
00738                              geo.y - top_corner_offset,
00739                              top_corner->GetWidth(),
00740                              top_corner->GetHeight(),
00741                              top_corner->GetDeviceTexture(),
00742                              texxform,
00743                              nux::color::White);
00744       }
00745       {
00746         // Top edge
00747         texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00748         texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
00749 
00750         gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00751         gfx_context.QRP_1Tex(geo.x + geo.width,
00752                              geo.y - 10,
00753                              geometry.width - (geo.x + geo.width),
00754                              top_tile->GetHeight(),
00755                              top_tile->GetDeviceTexture(),
00756                              texxform,
00757                              nux::color::White);
00758       }
00759 
00760       gfx_context.GetRenderStates().SetBlend(false);
00761     }
00762   }
00763 }
00764 
00765 void OverlayRendererImpl::DrawContent(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry)
00766 {
00767   nux::Geometry geo = geometry;
00768   bgs = 0;
00769 
00770   int excess_border = (Settings::Instance().GetFormFactor() != FormFactor::NETBOOK) ? EXCESS_BORDER : 0;
00771 
00772   nux::Geometry larger_content_geo = content_geo;
00773   larger_content_geo.OffsetSize(excess_border, excess_border);
00774 
00775   nux::Geometry larger_geo(larger_content_geo);
00776 
00777   nux::Geometry larger_absolute_geo = absolute_geo;
00778   larger_absolute_geo.OffsetSize(excess_border, excess_border);
00779   
00780 
00781   gfx_context.PushClippingRectangle(larger_geo);
00782 
00783   gfx_context.GetRenderStates().SetBlend(true);
00784   gfx_context.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
00785 
00786   nux::TexCoordXForm texxform_absolute_bg;
00787   texxform_absolute_bg.flip_v_coord = true;
00788   texxform_absolute_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00789   texxform_absolute_bg.uoffset = ((float) larger_content_geo.x) / absolute_geo.width;
00790   texxform_absolute_bg.voffset = ((float) larger_content_geo.y) / absolute_geo.height;
00791   texxform_absolute_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
00792 
00793   nux::ROPConfig rop;
00794   rop.Blend = false;
00795   rop.SrcBlend = GL_ONE;
00796   rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
00797 
00798   if (bg_blur_texture_.IsValid())
00799   {
00800 #ifndef NUX_OPENGLES_20
00801     if (gfx_context.UsingGLSLCodePath())
00802       gPainter.PushCompositionLayer(gfx_context, larger_content_geo,
00803                                     bg_blur_texture_,
00804                                     texxform_absolute_bg,
00805                                     nux::color::White,
00806                                     bg_color_, nux::LAYER_BLEND_MODE_OVERLAY,
00807                                     true, rop);
00808     else
00809       gPainter.PushTextureLayer(gfx_context, larger_content_geo,
00810                                 bg_blur_texture_,
00811                                 texxform_absolute_bg,
00812                                 nux::color::White,
00813                                 true, // write alpha?
00814                                 rop);
00815 #else
00816       gPainter.PushCompositionLayer(gfx_context, larger_content_geo,
00817                                     bg_blur_texture_,
00818                                     texxform_absolute_bg,
00819                                     nux::color::White,
00820                                     bg_color_, nux::LAYER_BLEND_MODE_OVERLAY,
00821                                     true, rop);
00822 #endif
00823     bgs++;
00824   }
00825 
00826   // draw the darkening behind our paint
00827   nux::GetPainter().PushLayer(gfx_context, bg_darken_layer_->GetGeometry(), bg_darken_layer_);
00828   bgs++;
00829 
00830 #ifndef NUX_OPENGLES_20
00831   if (gfx_context.UsingGLSLCodePath() == false)
00832   {
00833     nux::GetPainter().PushLayer(gfx_context, bg_layer_->GetGeometry(), bg_layer_);
00834     bgs++;
00835   }
00836 #endif
00837 
00838   // apply the shine
00839   rop.Blend = true;
00840   rop.SrcBlend = GL_DST_COLOR;
00841   rop.DstBlend = GL_ONE;
00842   texxform_absolute_bg.flip_v_coord = false;
00843   texxform_absolute_bg.uoffset = (1.0f / bg_shine_texture_->GetWidth()) * parent->x_offset;
00844   texxform_absolute_bg.voffset = (1.0f / bg_shine_texture_->GetHeight()) * parent->y_offset;
00845 
00846   nux::GetPainter().PushTextureLayer(gfx_context, larger_content_geo,
00847                                      bg_shine_texture_,
00848                                      texxform_absolute_bg,
00849                                      nux::color::White,
00850                                      false,
00851                                      rop);
00852   bgs++;
00853 }
00854 
00855 void OverlayRendererImpl::DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geometry)
00856 {
00857   nux::GetPainter().PopBackground(bgs);
00858 
00859   gfx_context.GetRenderStates().SetBlend(false);
00860   gfx_context.PopClippingRectangle();
00861 
00862   bgs = 0;
00863 }
00864 
00865 
00866 
00867 OverlayRenderer::OverlayRenderer()
00868   : pimpl_(new OverlayRendererImpl(this))
00869 {
00870 
00871 }
00872 
00873 
00874 OverlayRenderer::~OverlayRenderer()
00875 {
00876   delete pimpl_;
00877 }
00878 
00879 void OverlayRenderer::AboutToHide()
00880 {
00881   pimpl_->visible = false;
00882   pimpl_->bg_effect_helper_.enabled = false;
00883   need_redraw.emit();
00884 }
00885 
00886 void OverlayRenderer::AboutToShow()
00887 {
00888   pimpl_->ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
00889   pimpl_->visible = true;
00890   pimpl_->bg_effect_helper_.enabled = true;
00891   need_redraw.emit();
00892 }
00893 
00894 void OverlayRenderer::SetOwner(nux::View* owner)
00895 {
00896   pimpl_->bg_effect_helper_.owner= owner;
00897 }
00898 
00899 void OverlayRenderer::DisableBlur()
00900 {
00901   pimpl_->bg_effect_helper_.blur_type = BLUR_NONE;
00902 }
00903 
00904 void OverlayRenderer::DrawFull(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo, bool force_edges)
00905 {
00906   pimpl_->Draw(gfx_context, content_geo, absolute_geo, geo, force_edges);
00907   LOG_DEBUG(logger) << "OverlayRenderer::DrawFull(): content_geo:  " << content_geo.width << "/" << content_geo.height;
00908   LOG_DEBUG(logger) << "OverlayRenderer::DrawFull(): absolute_geo: " << absolute_geo.width << "/" << absolute_geo.height;
00909   LOG_DEBUG(logger) << "OverlayRenderer::DrawFull(): geo:          " << geo.width << "/" << geo.height;
00910 }
00911 
00912 void OverlayRenderer::DrawInner(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo)
00913 {
00914   pimpl_->DrawContent(gfx_context, content_geo, absolute_geo, geo);
00915   LOG_DEBUG(logger) << "OverlayRenderer::DrawInner(): content_geo:  " << content_geo.width << "/" << content_geo.height;
00916   LOG_DEBUG(logger) << "OverlayRenderer::DrawInner(): absolute_geo: " << absolute_geo.width << "/" << absolute_geo.height;
00917   LOG_DEBUG(logger) << "OverlayRenderer::DrawInner(): geo:          " << geo.width << "/" << geo.height;
00918 }
00919 
00920 void OverlayRenderer::DrawInnerCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry content_geo, nux::Geometry absolute_geo, nux::Geometry geo)
00921 {
00922   pimpl_->DrawContentCleanup(gfx_context, content_geo, absolute_geo, geo);
00923   LOG_DEBUG(logger) << "OverlayRenderer::DrawInnerCleanup(): content_geo:  " << content_geo.width << "/" << content_geo.height;
00924   LOG_DEBUG(logger) << "OverlayRenderer::DrawInnerCleanup(): absolute_geo: " << absolute_geo.width << "/" << absolute_geo.height;
00925   LOG_DEBUG(logger) << "OverlayRenderer::DrawInnerCleanup(): geo:          " << geo.width << "/" << geo.height;
00926 }
00927 
00928 }
00929 
00930