Example #1
0
File: video.c Project: zmike/compiz
static Bool
videoInitWindow(CompPlugin *p,
                CompWindow *w)
{
   VideoWindow *vw;

   VIDEO_SCREEN(w->screen);

   vw = malloc(sizeof (VideoWindow));
   if (!vw)
     return FALSE;

   vw->source = NULL;
   vw->context = NULL;

   w->base.privates[vs->windowPrivateIndex].ptr = vw;

   if (w->shaded || w->attrib.map_state == IsViewable)
     videoWindowUpdate(w);

   return TRUE;
}
static void
videoSetSupportedHint (CompScreen *s)
{
    Atom data[16];
    int  i, n = 0;

    VIDEO_DISPLAY (s->display);
    VIDEO_SCREEN (s);

    for (i = 0; i < IMAGE_FORMAT_NUM; i++)
    {
	if (!vs->imageFormat[i])
	    continue;

	if (i == 0 || vd->opt[i - 1].value.b)
	    data[n++] = vd->videoImageFormatAtom[i];
    }

    XChangeProperty (s->display->display, s->root,
		     vd->videoSupportedAtom, XA_ATOM, 32,
		     PropModeReplace, (unsigned char *) data, n);
}
Example #3
0
File: video.c Project: zmike/compiz
static void
videoWindowMoveNotify(CompWindow *w,
                      int dx,
                      int dy,
                      Bool immediate)
{
   VIDEO_SCREEN(w->screen);
   VIDEO_WINDOW(w);

   if (vw->context)
     {
        vw->context->box.extents.x1 += dx;
        vw->context->box.extents.y1 += dy;
        vw->context->box.extents.x2 += dx;
        vw->context->box.extents.y2 += dy;

        updateWindowVideoMatrix(w);
     }

   UNWRAP(vs, w->screen, windowMoveNotify);
   (*w->screen->windowMoveNotify)(w, dx, dy, immediate);
   WRAP(vs, w->screen, windowMoveNotify, videoWindowMoveNotify);
}
Example #4
0
File: video.c Project: zmike/compiz
static void
videoWindowUpdate(CompWindow *w)
{
   Atom actual;
   int result, format, i;
   unsigned long n, left;
   unsigned char *propData;
   VideoTexture *texture = NULL;
   Pixmap pixmap = None;
   Atom imageFormat = 0;
   decor_point_t p[2];
   int aspectX = 0;
   int aspectY = 0;
   int panScan = 0;
   int width = 0;
   int height = 0;

   VIDEO_DISPLAY(w->screen->display);
   VIDEO_SCREEN(w->screen);
   VIDEO_WINDOW(w);

   memset(p, 0, sizeof (p));

   result = XGetWindowProperty(w->screen->display->display, w->id,
                               vd->videoAtom, 0L, 13L, FALSE,
                               XA_INTEGER, &actual, &format,
                               &n, &left, &propData);

   if (result == Success && propData)
     {
        if (n == 13)
          {
             long *data = (long *)propData;

             pixmap = *data++;
             imageFormat = *data++;

             width = *data++;
             height = *data++;

             aspectX = *data++;
             aspectY = *data++;
             panScan = *data++;

             p[0].gravity = *data++;
             p[0].x = *data++;
             p[0].y = *data++;
             p[1].gravity = *data++;
             p[1].x = *data++;
             p[1].y = *data++;
          }

        XFree(propData);
     }

   for (i = 0; i < IMAGE_FORMAT_NUM; i++)
     if (vd->videoImageFormatAtom[i] == imageFormat)
       break;

   if (i < IMAGE_FORMAT_NUM)
     {
        if (!vs->imageFormat[i])
          {
             compLogMessage("video", CompLogLevelWarn,
                            "Image format not supported");
             i = IMAGE_FORMAT_NUM;
          }
     }

   if (i < IMAGE_FORMAT_NUM)
     {
        texture = videoGetTexture(w->screen, pixmap);
        if (!texture)
          {
             compLogMessage("video", CompLogLevelWarn,
                            "Bad pixmap 0x%x", (int)pixmap);
          }
     }

   if (vw->source)
     {
        videoReleaseTexture(w->screen, vw->source->texture);
     }
   else
     {
        vw->source = malloc(sizeof (VideoSource));
     }

   if (texture && vw->source)
     {
        vw->source->texture = texture;
        vw->source->format = i;
        vw->source->p1 = p[0];
        vw->source->p2 = p[1];
        vw->source->width = width;
        vw->source->height = height;
        vw->source->aspect = aspectX && aspectY;
        vw->source->panScan = panScan / 65536.0f;

        if (vw->source->aspect)
          vw->source->aspectRatio = (float)aspectX / aspectY;

        updateWindowVideoContext(w, vw->source);
     }
   else
     {
        if (texture)
          videoReleaseTexture(w->screen, texture);

        if (vw->source)
          {
             free(vw->source);
             vw->source = NULL;
          }

        if (vw->context)
          {
             free(vw->context);
             vw->context = NULL;
          }
     }
}
Example #5
0
File: video.c Project: zmike/compiz
static void
videoDrawWindowTexture(CompWindow *w,
                       CompTexture *texture,
                       const FragmentAttrib *attrib,
                       unsigned int mask)
{
   CompScreen *s = w->screen;

   VIDEO_SCREEN(s);
   VIDEO_WINDOW(w);

   if (vw->context)
     {
        VideoSource *src = vw->context->source;

        if (src->format == IMAGE_FORMAT_YV12 &&
            &src->texture->texture == texture)
          {
             FragmentAttrib fa = *attrib;
             int param, function;

             param = allocFragmentParameters(&fa, 2);

             function = getYV12FragmentFunction(s, texture, param);
             if (function)
               {
                  float minX, minY, maxX, maxY, y1, y2;

                  addFragmentFunction(&fa, function);

                  minX = COMP_TEX_COORD_X(&texture->matrix, 1.0f);
                  maxX = COMP_TEX_COORD_X(&texture->matrix, src->width - 1.0f);

                  y1 = COMP_TEX_COORD_Y(&texture->matrix, 1.0f);
                  y2 = COMP_TEX_COORD_Y(&texture->matrix, src->height - 1.0f);

                  minY = MIN(y1, y2);
                  maxY = MAX(y1, y2);

                  (*s->programEnvParameter4f)(GL_FRAGMENT_PROGRAM_ARB, param,
                                              minX, minY, maxX, maxY);

                  /* need to provide plane offsets when texture coordinates
                     are not normalized */
                  if (texture->target != GL_TEXTURE_2D)
                    {
                       float offsetX, offsetY;

                       offsetX = COMP_TEX_COORD_X(&texture->matrix,
                                                  src->width / 2);

                       if (s->glxPixmapFBConfigs[8].yInverted)
                         offsetY = COMP_TEX_COORD_Y(&texture->matrix,
                                                    src->height);
                       else
                         offsetY = COMP_TEX_COORD_Y(&texture->matrix,
                                                    -src->height / 2);

                       (*s->programEnvParameter4f)(GL_FRAGMENT_PROGRAM_ARB,
                                                   param + 1,
                                                   0.0f, offsetY, offsetX, 0.0f);
                    }
               }

             UNWRAP(vs, s, drawWindowTexture);
             (*s->drawWindowTexture)(w, texture, &fa, mask);
             WRAP(vs, s, drawWindowTexture, videoDrawWindowTexture);
          }
        else
          {
             if (!(mask & PAINT_WINDOW_BLEND_MASK))
               {
                  /* we don't have to draw client window texture when
                     video cover the full window and blending isn't used */
                  if (vw->context->full && texture == w->texture)
                    return;
               }

             UNWRAP(vs, s, drawWindowTexture);
             (*s->drawWindowTexture)(w, texture, attrib, mask);
             WRAP(vs, s, drawWindowTexture, videoDrawWindowTexture);
          }
     }
   else
     {
        UNWRAP(vs, s, drawWindowTexture);
        (*s->drawWindowTexture)(w, texture, attrib, mask);
        WRAP(vs, s, drawWindowTexture, videoDrawWindowTexture);
     }
}
Example #6
0
File: video.c Project: zmike/compiz
static int
getYV12FragmentFunction(CompScreen *s,
                        CompTexture *texture,
                        int param)
{
   VideoFunction *function;
   CompFunctionData *data;
   int target;

   VIDEO_SCREEN(s);

   if (texture->target == GL_TEXTURE_2D)
     target = COMP_FETCH_TARGET_2D;
   else
     target = COMP_FETCH_TARGET_RECT;

   for (function = vs->yv12Functions; function; function = function->next)
     if (function->param == param && function->target == target)
       return function->handle;

   data = createFunctionData();
   if (data)
     {
        static char *temp[] = { "uv", "tmp", "position" };
        int i, handle = 0;
        char str[1024];
        Bool ok = TRUE;

        for (i = 0; i < sizeof (temp) / sizeof (temp[0]); i++)
          ok &= addTempHeaderOpToFunctionData(data, temp[i]);

        snprintf(str, 1024,
                 "MOV position, fragment.texcoord[0];"
                 "MAX position, position, program.env[%d];"
                 "MIN position, position, program.env[%d].zwww;",
                 param, param);

        ok &= addDataOpToFunctionData(data, str);

        if (target == COMP_FETCH_TARGET_RECT)
          {
             snprintf(str, 1024,
                      "TEX output, position, texture[0], RECT;"
                      "MOV output, output.a;");

             ok &= addDataOpToFunctionData(data, str);

             if (s->glxPixmapFBConfigs[8].yInverted)
               {
                  snprintf(str, 1024,
                           "MAD position, position, 0.5, program.env[%d].xy;",
                           param + 1);
               }
             else
               {
                  snprintf(str, 1024,
                           "ADD position, position, program.env[%d].xy;"
                           "MUL position, position, 0.5;",
                           param + 1);
               }

             ok &= addDataOpToFunctionData(data, str);

             snprintf(str, 1024,
                      "TEX tmp, position, texture[0], RECT;"
                      "MOV uv, tmp.a;"
                      "MAD output, output, 1.164, -0.073;"
                      "ADD position.x, position.x, program.env[%d].z;"
                      "TEX tmp, position, texture[0], RECT;"
                      "MOV uv.y, tmp.a;",
                      param + 1);
          }
        else
          {
             snprintf(str, 1024,
                      "TEX output, position, texture[0], 2D;"
                      "MOV output, output.a;");

             ok &= addDataOpToFunctionData(data, str);

             if (s->glxPixmapFBConfigs[8].yInverted)
               {
                  snprintf(str, 1024,
                           "MAD position, position, 0.5, { 0.0, %f };",
                           2.0f / 3.0f);
               }
             else
               {
                  snprintf(str, 1024,
                           "SUB position, position, { 0.0, %f };"
                           "MUL position, position, 0.5;",
                           1.0f / 3.0f);
               }

             ok &= addDataOpToFunctionData(data, str);

             snprintf(str, 1024,
                      "TEX tmp, position, texture[0], 2D;"
                      "MOV uv, tmp.a;"
                      "MAD output, output, 1.164, -0.073;"
                      "ADD position.x, position.x, 0.5;"
                      "TEX tmp, position, texture[0], 2D;"
                      "MOV uv.y, tmp.a;");
          }

        ok &= addDataOpToFunctionData(data, str);

        snprintf(str, 1024,
                 "SUB uv, uv, { 0.5, 0.5 };"
                 "MAD output.xyz, { 1.596, -0.813,   0.0 }, uv.xxxw, output;"
                 "MAD output.xyz, {   0.0, -0.391, 2.018 }, uv.yyyw, output;"
                 "MOV output.a, 1.0;");

        ok &= addDataOpToFunctionData(data, str);

        if (!ok)
          {
             destroyFunctionData(data);
             return 0;
          }

        function = malloc(sizeof (VideoFunction));
        if (function)
          {
             handle = createFragmentFunction(s, "video", data);

             function->handle = handle;
             function->target = target;
             function->param = param;

             function->next = vs->yv12Functions;
             vs->yv12Functions = function;
          }

        destroyFunctionData(data);

        return handle;
     }

   return 0;
}