}
#endif
- if (pNode->__pFilter && pNode->__useFilter)
+ if (pNode->__pFilter && pNode->__useFilter && pNode->__pFilter->IsEnabled())
{
- _VisualElementFilterImpl* pFilterImpl = _VisualElementFilterImpl::GetInstance(*pNode->__pFilter);
+ shaderType |= SHADER_TYPE_BLUR;
- if (pFilterImpl->IsEnabled())
- {
- shaderType |= SHADER_TYPE_BLUR;
-
- __pFilter = pNode->__pFilter;
- }
+ __pFilter = pNode->__pFilter;
}
if (likely(!pNode->__pMesh))
if (__pRenderQueue[i].__pFilter)
{
_VisualElementFilterImpl* pFilterImpl = _VisualElementFilterImpl::GetInstance(*__pRenderQueue[i].__pFilter);
+ float x, y;
+
+ if (pFilterImpl->__isFirstPass)
+ {
+ x = 1.0f / __pRenderQueue[i].__pSurfaceInfo->width;
+ y = 0.0f;
+ }
+ else
+ {
+ x = 0.0f;
+ y = 1.0f / __pRenderQueue[i].__pSurfaceInfo->height;
+ }
- glUniform1i(glGetUniformLocation(pProgramImpl->__program, "u_blurSize"), pFilterImpl->__kernelSize);
- glUniform1i(glGetUniformLocation(pProgramImpl->__program, "u_horizontalPass"), pFilterImpl->__isFirstPass ? 1 : 0);
+ glUniform1f(glGetUniformLocation(pProgramImpl->__program, "u_radius"), pFilterImpl->__radius);
glUniform1f(glGetUniformLocation(pProgramImpl->__program, "u_sigma"), pFilterImpl->__sigma);
- glUniform2f(glGetUniformLocation(pProgramImpl->__program, "u_texcoordOffset"), 1.0f / __pRenderQueue[i].__pSurfaceInfo->width, 1.0f / __pRenderQueue[i].__pSurfaceInfo->height);
+ glUniform2f(glGetUniformLocation(pProgramImpl->__program, "u_directionVec"), x, y);
}
}
else
useStencil |= (pNode->__useStencil) ? true : false;
updateStencil = (pNode->__useStencil && pChildImpl->GetChildrenCount() > 0) ? true : false;
- if (pNode->__pFilter)
+ if (pNode->__pFilter && pNode->__pFilter->IsEnabled())
{
_VisualElementFilterImpl* pFilterImpl = _VisualElementFilterImpl::GetInstance(*pNode->__pFilter);
bool useTempNode = false;
pNode->__useFilter = false;
+ glViewport(0, 0, pRenderTextureInfo->width, pRenderTextureInfo->height);
+
EnqueueRenderObject(pNode, false, 0, true);
FlushRenderQueue();
pFilterImpl->__isFirstPass = true;
+ glViewport(0, 0, pInternalTextureInfo->width, pInternalTextureInfo->height);
+
if (useTempNode)
{
__pTempNode->__useBlend = pNode->__useBlend;
__pTempNode->__textureId = textureId;
__pTempNode->__pSurface = pSurface;
+ glViewport(__viewport.x, __viewport.y, __viewport.width, __viewport.height);
+
EnqueueRenderObject(__pTempNode, useStencil, stencilIndex, true);
}
else
#define BLUR_FUNCTION L"vec4 blur(void)\n"\
"{\n"\
- " float numBlurPixelsPerSide = float(u_blurSize / 2);\n"\
- " vec2 blurMultiplyVec = u_horizontalPass > 0 ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n"\
- "\n"\
" vec3 incrementalGaussian;\n"\
- " incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * u_sigma);\n"\
+ " incrementalGaussian.x = 1.0 / (sqrt_pi2 * u_sigma);\n"\
" incrementalGaussian.y = exp(-0.5 / (u_sigma * u_sigma));\n"\
" incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;\n"\
"\n"\
" vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);\n"\
" float coefficientSum = 0.0;\n"\
"\n"\
- " avgValue += texture2D(u_tex2d, v_texcoord).bgra * incrementalGaussian.x;\n"\
- " coefficientSum += incrementalGaussian.x;\n"\
+ " avgValue = texture2D(u_tex2d, v_texcoord).bgra * incrementalGaussian.x;\n"\
+ " coefficientSum = incrementalGaussian.x;\n"\
" incrementalGaussian.xy *= incrementalGaussian.yz;\n"\
"\n"\
- " for (float i = 1.0; i <= numBlurPixelsPerSide; i++)\n"\
+ " for (float i = 1.0; i <= u_radius; i++)\n"\
" {\n"\
- " avgValue += texture2D(u_tex2d, v_texcoord.st - i * u_texcoordOffset * blurMultiplyVec).bgra * incrementalGaussian.x;\n"\
- " avgValue += texture2D(u_tex2d, v_texcoord.st + i * u_texcoordOffset * blurMultiplyVec).bgra * incrementalGaussian.x;\n"\
+ " avgValue += texture2D(u_tex2d, v_texcoord.st - i * u_directionVec).bgra * incrementalGaussian.x;\n"\
+ " avgValue += texture2D(u_tex2d, v_texcoord.st + i * u_directionVec).bgra * incrementalGaussian.x;\n"\
" coefficientSum += 2.0 * incrementalGaussian.x;\n"\
" incrementalGaussian.xy *= incrementalGaussian.yz;\n"\
" }\n"\
if (blur)
{
- InsertUniform(L"int", L"u_blurSize", fragmentShader);
- InsertUniform(L"int", L"u_horizontalPass", fragmentShader);
+ InsertUniform(L"float", L"u_radius", fragmentShader);
InsertUniform(L"float", L"u_sigma", fragmentShader);
- InsertUniform(L"vec2", L"u_texcoordOffset", fragmentShader);
+ InsertUniform(L"vec2", L"u_directionVec", fragmentShader);
- InsertVariable(L"const float", L"pi", L"3.14159265", fragmentShader);
+ InsertVariable(L"const float", L"sqrt_pi2", L"2.50662827", fragmentShader);
InsertFunction(BLUR_FUNCTION, fragmentShader);
#include "FUiAnim_NativeLayer.h"
#include "FUiAnim_VisualElementFilterImpl.h"
+#define SMALL_SURFACE_SIZE 100
+
#define PRINT(...) fprintf(stderr, __VA_ARGS__)
//#define PRINT(...)
_VisualElementFilterImpl::_VisualElementFilterImpl(void)
: __type(VisualElementFilter::TYPE_BLUR)
- , __isFirstPass(true)
, __size()
+ , __surfaceSize()
, __pInternalSurface(null)
, __pRenderSurface(null)
, __enabled(true)
, __kernelSize(0.0f)
+ , __radius(0.0f)
, __sigma(0.0f)
+ , __needRenderSurface(false)
+ , __isFirstPass(true)
{
}
__kernelSize = kernelSize;
- __sigma = __kernelSize / 2;
+ CalcFilterInfo();
return E_SUCCESS;
}
bool
_VisualElementFilterImpl::Prepare(const _NativeLayer& layer, const Tizen::Graphics::Dimension& size, bool needRenderSurface)
{
- if (__size == size)
- {
- return true;
- }
-
- DisplayContext* pDisplayContext = layer.GetDisplayContext();
-
- if (__type == VisualElementFilter::TYPE_BLUR)
- {
- // create internal surface
- __pInternalSurface = new (std::nothrow) VisualElementSurface();
-
- __pInternalSurface->Construct(*pDisplayContext, size, SURFACE_RENDER_TARGET);
- }
-
- if (__pRenderSurface)
- {
- delete __pRenderSurface;
- __pRenderSurface = null;
- }
+// if (!__enabled)
+// {
+// return true;
+// }
- if (needRenderSurface)
+ if (__size != size || __needRenderSurface != needRenderSurface)
{
- __pRenderSurface = new (std::nothrow) VisualElementSurface();
-
- __pRenderSurface->Construct(*pDisplayContext, size, SURFACE_RENDER_TARGET);
+ DisplayContext* pDisplayContext = layer.GetDisplayContext();
+ Tizen::Graphics::Dimension surfaceSize;
+
+ if (size.width < SMALL_SURFACE_SIZE || size.height < SMALL_SURFACE_SIZE)
+ {
+ surfaceSize = size;
+ }
+ else
+ {
+ surfaceSize.width = size.width / 2;
+ surfaceSize.height = size.height / 2;
+
+ needRenderSurface = true;
+ }
+
+ if (__type == VisualElementFilter::TYPE_BLUR)
+ {
+ if (__surfaceSize != surfaceSize)
+ {
+ if (__pInternalSurface)
+ {
+ delete __pInternalSurface;
+ __pInternalSurface = null;
+ }
+
+ // create internal surface
+ __pInternalSurface = new (std::nothrow) VisualElementSurface();
+
+ __pInternalSurface->Construct(*pDisplayContext, surfaceSize, SURFACE_RENDER_TARGET);
+ }
+ }
+
+ if (needRenderSurface)
+ {
+ if (__surfaceSize != surfaceSize)
+ {
+ if (__pRenderSurface)
+ {
+ delete __pRenderSurface;
+ __pRenderSurface = null;
+ }
+
+ __pRenderSurface = new (std::nothrow) VisualElementSurface();
+
+ __pRenderSurface->Construct(*pDisplayContext, surfaceSize, SURFACE_RENDER_TARGET);
+ }
+ }
+ else
+ {
+ if (__pRenderSurface)
+ {
+ delete __pRenderSurface;
+ __pRenderSurface = null;
+ }
+ }
+
+ __size = size;
+ __surfaceSize = surfaceSize;
+ __needRenderSurface = needRenderSurface;
+
+ CalcFilterInfo();
}
return true;
return filter.__pVisualElementFilterImpl;
}
+void
+_VisualElementFilterImpl::CalcFilterInfo(void)
+{
+ if (__size == __surfaceSize)
+ {
+ __radius = __kernelSize / 2;
+ }
+ else
+ {
+ __radius = __kernelSize / 4;
+ }
+
+ __sigma = __kernelSize / 2;
+}
+
}}} // Tizen::Ui::Animations
private:
_VisualElementFilterImpl& operator =(const _VisualElementFilterImpl& rhs);
+ void CalcFilterInfo(void);
+
private:
VisualElementFilter::FilterType __type;
- bool __isFirstPass;
Tizen::Graphics::Dimension __size;
+ Tizen::Graphics::Dimension __surfaceSize;
VisualElementSurface* __pInternalSurface;
VisualElementSurface* __pRenderSurface;
bool __enabled;
float __kernelSize;
+ float __radius;
float __sigma;
+ bool __needRenderSurface;
+ bool __isFirstPass;
+
friend class _GlRenderManager;
}; // _VisualElementFilterImpl