/* Prints a vertex, in 16.16 fixed-point form */ void PrintVertex(struct Point3 *Vec) { long X = DOUBLE_TO_FIXED(Vec->X); long Y = DOUBLE_TO_FIXED(Vec->Y); long Z = DOUBLE_TO_FIXED(Vec->Z); Pointlist[NumPoints++] = *Vec; /* remember this point */ fprintf(OutputFile, "{%ld, %ld, %ld},\n", X, Y, Z); }
void IOHIDParametricAcceleration::serialize(CFMutableDictionaryRef dict) const { CFMutableDictionaryRefWrap serializer (dict); serializer.SetValueForKey(CFSTR("Class"), CFSTR("IOHIDParametricAcceleration")); serializer.SetValueForKey(CFSTR("AccelIndex"), DOUBLE_TO_FIXED(accel.Index)); serializer.SetValueForKey(CFSTR("GainLinear"), DOUBLE_TO_FIXED(accel.GainLinear)); serializer.SetValueForKey(CFSTR("GainCubic"), DOUBLE_TO_FIXED(accel.GainCubic)); serializer.SetValueForKey(CFSTR("TangentSpeedLinear"), DOUBLE_TO_FIXED(accel.TangentSpeedLinear)); serializer.SetValueForKey(CFSTR("TangentSpeedParabolicRoot"), DOUBLE_TO_FIXED(accel.TangentSpeedParabolicRoot)); }
void IOHIDTableAcceleration::serialize(CFMutableDictionaryRef dict) const { CFMutableDictionaryRefWrap serializer (dict); serializer.SetValueForKey(CFSTR("Class"), CFSTR("IOHIDTableAcceleration")); CFMutableArrayRefWrap curves; for (auto iter = segments_.begin() ; iter != segments_.end() ; ++iter) { curves.Append(CFDictionaryRefWrap( {CFSTR("m"),CFSTR("b"),CFSTR("x")}, {CFNumberRefWrap(DOUBLE_TO_FIXED(iter->m)),CFNumberRefWrap(DOUBLE_TO_FIXED(iter->b)),CFNumberRefWrap(DOUBLE_TO_FIXED(iter->x))}) ); } serializer.SetValueForKey(CFSTR("Curves"), curves); }
void waveform_float_wavetable_sine_mix(float_waveform_t *waveform, float_oscillator_t *osc, float *sample_buffer, int sample_count) { fixed_t frequency_ratio = DOUBLE_TO_FIXED(osc->frequency / waveform->frequency); fixed_t phase_step = fixed_mul(frequency_ratio, waveform->phase_step); float amplitude_step = (osc->level - osc->last_level) / sample_count; float amplitude_scale = osc->last_level; while (sample_count > 0) { int sample_index = fixed_mul(osc->phase_fixed, waveform->sample_count); float sample = waveform->samples[sample_index]; sample *= amplitude_scale; sample += *sample_buffer; *sample_buffer++ = sample; *sample_buffer++ = sample; osc->phase_fixed += phase_step; if (osc->phase_fixed >= FIXED_ONE) { osc->phase_fixed -= FIXED_ONE; } amplitude_scale += amplitude_step; sample_count--; } }
void float_generate_sine(float_waveform_t *waveform, float sample_rate, float frequency) { static float max_phase = 1.0f; float phase_step_float = max_phase * frequency / sample_rate; waveform->frequency = frequency; waveform->phase_step = DOUBLE_TO_FIXED(phase_step_float); waveform->sample_count = roundf(max_phase / phase_step_float); waveform->samples = malloc(waveform->sample_count * sizeof(waveform->samples[0])); float phase; for (int i = 0; i < waveform->sample_count; i++) { phase = i * phase_step_float; waveform->samples[i] = sinf(phase * M_PI * 2.0f); } }
void zoom_process(const ZoomInfo *zi, const uint8_t *src, uint8_t *dest) { int from_stride, to_stride; const uint8_t *from; uint8_t *to; from = src; from_stride = zi->old_stride; /* Apply filter to zoom horizontally from src to tmp (if necessary) */ if (zi->x_contrib) { int y; to = zi->tmpimage; to_stride = zi->new_w * zi->Bpp; for (y = 0; y < zi->old_h; y++, from += from_stride, to += to_stride) { int32_t *contrib = zi->x_contrib; int x; for (x = 0; x < zi->new_w * zi->Bpp; x++) { int32_t weight = DOUBLE_TO_FIXED(0.5); int n = *contrib++, i; for (i = 0; i < n; i++) { int pixel = *contrib++; weight += from[pixel] * (*contrib++); } to[x] = CLAMP(FIXED_TO_INT(weight), 0, 255); } } from = zi->tmpimage; from_stride = to_stride; } /* Apply filter to zoom vertically from tmp (or src) to dest */ /* Use Y as the outside loop to avoid cache thrashing on output buffer */ to = dest; to_stride = zi->new_stride; if (zi->y_contrib) { int32_t *contrib = zi->y_contrib; int y; for (y = 0; y < zi->new_h; y++, to += to_stride) { int n = *contrib++, x; for (x = 0; x < zi->new_w * zi->Bpp; x++) { int32_t weight = DOUBLE_TO_FIXED(0.5); int i; for (i = 0; i < n; i++) { int pixel = contrib[i*2]; weight += from[x+pixel] * contrib[i*2+1]; } to[x] = CLAMP(FIXED_TO_INT(weight), 0, 255); } contrib += 2*n; } } else { /* No zooming necessary, just copy */ if (from_stride == zi->new_w*zi->Bpp && to_stride == zi->new_w*zi->Bpp ) { /* We can copy the whole frame at once */ ac_memcpy(to, from, to_stride * zi->new_h); } else { /* Copy one row at a time */ int y; for (y = 0; y < zi->new_h; y++) { ac_memcpy(to + y*to_stride, from + y*from_stride, zi->new_w * zi->Bpp); } } } }
ZoomInfo *zoom_init(int old_w, int old_h, int new_w, int new_h, int Bpp, int old_stride, int new_stride, TCVZoomFilter filter) { ZoomInfo *zi; struct clist *x_contrib = NULL, *y_contrib = NULL; /* Sanity check */ if (old_w <= 0 || old_h <= 0 || new_w <= 0 || new_h <= 0 || Bpp <= 0 || old_stride <= 0 || new_stride <= 0) return NULL; /* Allocate structure */ zi = tc_malloc(sizeof(*zi)); if (!zi) return NULL; /* Set up scalar members, and check filter value */ zi->old_w = old_w; zi->old_h = old_h; zi->new_w = new_w; zi->new_h = new_h; zi->Bpp = Bpp; zi->old_stride = old_stride; zi->new_stride = new_stride; switch (filter) { case TCV_ZOOM_BOX: zi->filter = box_filter; zi->fwidth = box_support; break; case TCV_ZOOM_TRIANGLE: zi->filter = triangle_filter; zi->fwidth = triangle_support; break; case TCV_ZOOM_HERMITE: zi->filter = hermite_filter; zi->fwidth = hermite_support; break; case TCV_ZOOM_BELL: zi->filter = bell_filter; zi->fwidth = bell_support; break; case TCV_ZOOM_B_SPLINE: zi->filter = B_spline_filter; zi->fwidth = B_spline_support; break; case TCV_ZOOM_MITCHELL: zi->filter = mitchell_filter; zi->fwidth = mitchell_support; break; case TCV_ZOOM_LANCZOS3: zi->filter = lanczos3_filter; zi->fwidth = lanczos3_support; break; case TCV_ZOOM_CUBIC_KEYS4: zi->filter = cubic_keys4_filter; zi->fwidth = cubic_keys4_support; break; case TCV_ZOOM_SINC8: zi->filter = sinc8_filter; zi->fwidth = sinc8_support; break; default: free(zi); return NULL; } /* Generate contributor lists and allocate temporary image buffer */ zi->x_contrib = NULL; zi->y_contrib = NULL; zi->tmpimage = tc_malloc(new_w * old_h * Bpp); if (!zi->tmpimage) goto error_out; if (old_w != new_w) { x_contrib = gen_contrib(old_w, new_w, Bpp, zi->filter, zi->fwidth); if (!x_contrib) goto error_out; } if (old_h != new_h) { /* Calculate the correct stride--if the width isn't changing, * this will just be old_stride */ int stride = (old_w==new_w) ? old_stride : Bpp*new_w; y_contrib = gen_contrib(old_h, new_h, stride, zi->filter, zi->fwidth); if (!y_contrib) goto error_out; } /* Convert contributor lists into flat arrays and fixed-point values. * The flat array consists of a contributor count plus two values per * contributor (index and fixed-point weight) for each output pixel. * Note that for the horizontal direction, we make `Bpp' copies of the * contributors, adjusting the offset for each byte of the pixel. */ if (x_contrib) { int count = 0, i; int32_t *ptr; for (i = 0; i < new_w; i++) count += 1 + 2 * x_contrib[i].n; zi->x_contrib = tc_malloc(sizeof(int32_t) * count * Bpp); if (!zi->x_contrib) goto error_out; for (ptr = zi->x_contrib, i = 0; i < new_w * Bpp; i++) { int j; *ptr++ = x_contrib[i/Bpp].n; for (j = 0; j < x_contrib[i/Bpp].n; j++) { *ptr++ = x_contrib[i/Bpp].list[j].pixel + i%Bpp; *ptr++ = DOUBLE_TO_FIXED(x_contrib[i/Bpp].list[j].weight); } } /* Free original contributor list */ for (i = 0; i < new_w; i++) free(x_contrib[i].list); free(x_contrib); x_contrib = NULL; } if (y_contrib) { int count = 0, i; int32_t *ptr; for (i = 0; i < new_h; i++) count += 1 + 2 * y_contrib[i].n; zi->y_contrib = tc_malloc(sizeof(int32_t) * count); if (!zi->y_contrib) goto error_out; for (ptr = zi->y_contrib, i = 0; i < new_h; i++) { int j; *ptr++ = y_contrib[i].n; for (j = 0; j < y_contrib[i].n; j++) { *ptr++ = y_contrib[i].list[j].pixel; *ptr++ = DOUBLE_TO_FIXED(y_contrib[i].list[j].weight); } } for (i = 0; i < new_h; i++) free(y_contrib[i].list); free(y_contrib); y_contrib = NULL; } /* Done */ return zi; error_out: { if (x_contrib) { int i; for (i = 0; i < new_w; i++) free(x_contrib[i].list); free(x_contrib); } if (y_contrib) { int i; for (i = 0; i < new_w; i++) free(x_contrib[i].list); free(x_contrib); } zoom_free(zi); return NULL; } }
void TrackMouseEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { effects->paintScreen(mask, region, data); // paint normal screen if (!m_active) return; if ( effects->isOpenGLCompositing() && m_texture[0] && m_texture[1]) { ShaderBinder binder(ShaderManager::GenericShader); GLShader *shader(binder.shader()); if (!shader) { return; } QMatrix4x4 modelview; modelview = shader->getUniformMatrix4x4("modelview"); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); QMatrix4x4 matrix(modelview); const QPointF p = m_lastRect[0].topLeft() + QPoint(m_lastRect[0].width()/2.0, m_lastRect[0].height()/2.0); const float x = p.x()*data.xScale() + data.xTranslation(); const float y = p.y()*data.yScale() + data.yTranslation(); for (int i = 0; i < 2; ++i) { matrix.translate(x, y, 0.0); matrix.rotate(i ? -2*m_angle : m_angle, 0, 0, 1.0); matrix.translate(-x, -y, 0.0); shader->setUniform(GLShader::ModelViewMatrix, matrix); shader->setUniform(GLShader::Saturation, 1.0); shader->setUniform(GLShader::ModulationConstant, QVector4D(1.0, 1.0, 1.0, 1.0)); m_texture[i]->bind(); m_texture[i]->render(region, m_lastRect[i]); m_texture[i]->unbind(); } glDisable(GL_BLEND); shader->setUniform(GLShader::ModelViewMatrix, modelview); } #ifdef KWIN_HAVE_XRENDER_COMPOSITING if ( effects->compositingType() == XRenderCompositing && m_picture[0] && m_picture[1]) { float sine = sin(m_angle); const float cosine = cos(m_angle); for (int i = 0; i < 2; ++i) { if (i) sine = -sine; const float dx = m_size[i].width()/2.0; const float dy = m_size[i].height()/2.0; const xcb_render_picture_t picture = *m_picture[i]; #define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536)) xcb_render_transform_t xform = { DOUBLE_TO_FIXED( cosine ), DOUBLE_TO_FIXED( -sine ), DOUBLE_TO_FIXED( dx - cosine*dx + sine*dy ), DOUBLE_TO_FIXED( sine ), DOUBLE_TO_FIXED( cosine ), DOUBLE_TO_FIXED( dy - sine*dx - cosine*dy ), DOUBLE_TO_FIXED( 0.0 ), DOUBLE_TO_FIXED( 0.0 ), DOUBLE_TO_FIXED( 1.0 ) }; #undef DOUBLE_TO_FIXED xcb_render_set_picture_transform(xcbConnection(), picture, xform); xcb_render_set_picture_filter(xcbConnection(), picture, 8, "bilinear", 0, NULL); const QRect &rect = m_lastRect[i]; xcb_render_composite(xcbConnection(), XCB_RENDER_PICT_OP_OVER, picture, XCB_RENDER_PICTURE_NONE, effects->xrenderBufferPicture(), 0, 0, 0, 0, qRound((rect.x()+rect.width()/2.0)*data.xScale() - rect.width()/2.0 + data.xTranslation()), qRound((rect.y()+rect.height()/2.0)*data.yScale() - rect.height()/2.0 + data.yTranslation()), rect.width(), rect.height()); } } #endif if (effects->compositingType() == QPainterCompositing && !m_image[0].isNull() && !m_image[1].isNull()) { QPainter *painter = effects->scenePainter(); const QPointF p = m_lastRect[0].topLeft() + QPoint(m_lastRect[0].width()/2.0, m_lastRect[0].height()/2.0); for (int i = 0; i < 2; ++i) { painter->save(); painter->translate(p.x(), p.y()); painter->rotate(i ? -2*m_angle : m_angle); painter->translate(-p.x(), -p.y()); painter->drawImage(m_lastRect[i], m_image[i]); painter->restore(); } } }
// paint the window void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintData data) { setTransformedShape(QRegion()); // maybe nothing will be painted // check if there is something to paint bool opaque = isOpaque() && qFuzzyCompare(data.opacity(), 1.0); /* HACK: It seems this causes painting glitches, disable temporarily if (( mask & PAINT_WINDOW_OPAQUE ) ^ ( mask & PAINT_WINDOW_TRANSLUCENT )) { // We are only painting either opaque OR translucent windows, not both if ( mask & PAINT_WINDOW_OPAQUE && !opaque ) return; // Only painting opaque and window is translucent if ( mask & PAINT_WINDOW_TRANSLUCENT && opaque ) return; // Only painting translucent and window is opaque }*/ // Intersect the clip region with the rectangle the window occupies on the screen if (!(mask & (PAINT_WINDOW_TRANSFORMED | PAINT_SCREEN_TRANSFORMED))) region &= toplevel->visibleRect(); if (region.isEmpty()) return; XRenderWindowPixmap *pixmap = windowPixmap<XRenderWindowPixmap>(); if (!pixmap || !pixmap->isValid()) { return; } xcb_render_picture_t pic = pixmap->picture(); if (pic == XCB_RENDER_PICTURE_NONE) // The render format can be null for GL and/or Xv visuals return; toplevel->resetDamage(); // set picture filter if (options->isXrenderSmoothScale()) { // only when forced, it's slow if (mask & PAINT_WINDOW_TRANSFORMED) filter = ImageFilterGood; else if (mask & PAINT_SCREEN_TRANSFORMED) filter = ImageFilterGood; else filter = ImageFilterFast; } else filter = ImageFilterFast; // do required transformations const QRect wr = mapToScreen(mask, data, QRect(0, 0, width(), height())); QRect cr = QRect(toplevel->clientPos(), toplevel->clientSize()); // Client rect (in the window) qreal xscale = 1; qreal yscale = 1; bool scaled = false; Client *client = dynamic_cast<Client*>(toplevel); Deleted *deleted = dynamic_cast<Deleted*>(toplevel); const QRect decorationRect = toplevel->decorationRect(); if (((client && !client->noBorder()) || (deleted && !deleted->noBorder())) && true) { // decorated client transformed_shape = decorationRect; if (toplevel->shape()) { // "xeyes" + decoration transformed_shape -= cr; transformed_shape += shape(); } } else { transformed_shape = shape(); } if (toplevel->hasShadow()) transformed_shape |= toplevel->shadow()->shadowRegion(); xcb_render_transform_t xform = { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; static const xcb_render_transform_t identity = { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; if (mask & PAINT_WINDOW_TRANSFORMED) { xscale = data.xScale(); yscale = data.yScale(); } if (mask & PAINT_SCREEN_TRANSFORMED) { xscale *= screen_paint.xScale(); yscale *= screen_paint.yScale(); } if (!qFuzzyCompare(xscale, 1.0) || !qFuzzyCompare(yscale, 1.0)) { scaled = true; xform.matrix11 = DOUBLE_TO_FIXED(1.0 / xscale); xform.matrix22 = DOUBLE_TO_FIXED(1.0 / yscale); // transform the shape for clipping in paintTransformedScreen() QVector<QRect> rects = transformed_shape.rects(); for (int i = 0; i < rects.count(); ++i) { QRect& r = rects[ i ]; r.setRect(qRound(r.x() * xscale), qRound(r.y() * yscale), qRound(r.width() * xscale), qRound(r.height() * yscale)); } transformed_shape.setRects(rects.constData(), rects.count()); } transformed_shape.translate(mapToScreen(mask, data, QPoint(0, 0))); PaintClipper pcreg(region); // clip by the region to paint PaintClipper pc(transformed_shape); // clip by window's shape const bool wantShadow = m_shadow && !m_shadow->shadowRegion().isEmpty(); // In order to obtain a pixel perfect rescaling // we need to blit the window content togheter with // decorations in a temporary pixmap and scale // the temporary pixmap at the end. // We should do this only if there is scaling and // the window has border // This solves a number of glitches and on top of this // it optimizes painting quite a bit const bool blitInTempPixmap = xRenderOffscreen() || (data.crossFadeProgress() < 1.0 && !opaque) || (scaled && (wantShadow || (client && !client->noBorder()) || (deleted && !deleted->noBorder()))); xcb_render_picture_t renderTarget = m_scene->bufferPicture(); if (blitInTempPixmap) { if (scene_xRenderOffscreenTarget()) { temp_visibleRect = toplevel->visibleRect().translated(-toplevel->pos()); renderTarget = *scene_xRenderOffscreenTarget(); } else { prepareTempPixmap(); renderTarget = *s_tempPicture; } } else { xcb_render_set_picture_transform(connection(), pic, xform); if (filter == ImageFilterGood) { setPictureFilter(pic, KWin::Scene::ImageFilterGood); } //BEGIN OF STUPID RADEON HACK // This is needed to avoid hitting a fallback in the radeon driver. // The Render specification states that sampling pixels outside the // source picture results in alpha=0 pixels. This can be achieved by // setting the border color to transparent black, but since the border // color has the same format as the texture, it only works when the // texture has an alpha channel. So the driver falls back to software // when the repeat mode is RepeatNone, the picture has a non-identity // transformation matrix, and doesn't have an alpha channel. // Since we only scale the picture, we can work around this by setting // the repeat mode to RepeatPad. if (!window()->hasAlpha()) { const uint32_t values[] = {XCB_RENDER_REPEAT_PAD}; xcb_render_change_picture(connection(), pic, XCB_RENDER_CP_REPEAT, values); } //END OF STUPID RADEON HACK } #define MAP_RECT_TO_TARGET(_RECT_) \ if (blitInTempPixmap) _RECT_.translate(-temp_visibleRect.topLeft()); else _RECT_ = mapToScreen(mask, data, _RECT_) //BEGIN deco preparations bool noBorder = true; xcb_render_picture_t left = XCB_RENDER_PICTURE_NONE; xcb_render_picture_t top = XCB_RENDER_PICTURE_NONE; xcb_render_picture_t right = XCB_RENDER_PICTURE_NONE; xcb_render_picture_t bottom = XCB_RENDER_PICTURE_NONE; QRect dtr, dlr, drr, dbr; const SceneXRenderDecorationRenderer *renderer = nullptr; if (client) { if (client && !client->noBorder()) { if (client->isDecorated()) { SceneXRenderDecorationRenderer *r = static_cast<SceneXRenderDecorationRenderer*>(client->decoratedClient()->renderer()); if (r) { r->render(); renderer = r; } } noBorder = client->noBorder(); client->layoutDecorationRects(dlr, dtr, drr, dbr); } } if (deleted && !deleted->noBorder()) { renderer = static_cast<const SceneXRenderDecorationRenderer*>(deleted->decorationRenderer()); noBorder = deleted->noBorder(); deleted->layoutDecorationRects(dlr, dtr, drr, dbr); } if (renderer) { left = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Left); top = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Top); right = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Right); bottom = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Bottom); } if (!noBorder) { MAP_RECT_TO_TARGET(dtr); MAP_RECT_TO_TARGET(dlr); MAP_RECT_TO_TARGET(drr); MAP_RECT_TO_TARGET(dbr); } //END deco preparations //BEGIN shadow preparations QRect stlr, str, strr, srr, sbrr, sbr, sblr, slr; SceneXRenderShadow* m_xrenderShadow = static_cast<SceneXRenderShadow*>(m_shadow); if (wantShadow) { m_xrenderShadow->layoutShadowRects(str, strr, srr, sbrr, sbr, sblr, slr, stlr); MAP_RECT_TO_TARGET(stlr); MAP_RECT_TO_TARGET(str); MAP_RECT_TO_TARGET(strr); MAP_RECT_TO_TARGET(srr); MAP_RECT_TO_TARGET(sbrr); MAP_RECT_TO_TARGET(sbr); MAP_RECT_TO_TARGET(sblr); MAP_RECT_TO_TARGET(slr); } //BEGIN end preparations //BEGIN client preparations QRect dr = cr; if (blitInTempPixmap) { dr.translate(-temp_visibleRect.topLeft()); } else { dr = mapToScreen(mask, data, dr); // Destination rect if (scaled) { cr.moveLeft(cr.x() * xscale); cr.moveTop(cr.y() * yscale); } } const int clientRenderOp = (opaque || blitInTempPixmap) ? XCB_RENDER_PICT_OP_SRC : XCB_RENDER_PICT_OP_OVER; //END client preparations #undef MAP_RECT_TO_TARGET for (PaintClipper::Iterator iterator; !iterator.isDone(); iterator.next()) { #define RENDER_SHADOW_TILE(_TILE_, _RECT_) \ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, m_xrenderShadow->picture(SceneXRenderShadow::ShadowElement##_TILE_), \ shadowAlpha, renderTarget, 0, 0, 0, 0, _RECT_.x(), _RECT_.y(), _RECT_.width(), _RECT_.height()) //shadow if (wantShadow) { xcb_render_picture_t shadowAlpha = XCB_RENDER_PICTURE_NONE; if (!opaque) { shadowAlpha = xRenderBlendPicture(data.opacity()); } RENDER_SHADOW_TILE(TopLeft, stlr); RENDER_SHADOW_TILE(Top, str); RENDER_SHADOW_TILE(TopRight, strr); RENDER_SHADOW_TILE(Left, slr); RENDER_SHADOW_TILE(Right, srr); RENDER_SHADOW_TILE(BottomLeft, sblr); RENDER_SHADOW_TILE(Bottom, sbr); RENDER_SHADOW_TILE(BottomRight, sbrr); } #undef RENDER_SHADOW_TILE // Paint the window contents if (!(client && client->isShade())) { xcb_render_picture_t clientAlpha = XCB_RENDER_PICTURE_NONE; if (!opaque) { clientAlpha = xRenderBlendPicture(data.opacity()); } xcb_render_composite(connection(), clientRenderOp, pic, clientAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); if (data.crossFadeProgress() < 1.0 && data.crossFadeProgress() > 0.0) { XRenderWindowPixmap *previous = previousWindowPixmap<XRenderWindowPixmap>(); if (previous && previous != pixmap) { static XRenderPicture cFadeAlpha(XCB_RENDER_PICTURE_NONE); static xcb_render_color_t cFadeColor = {0, 0, 0, 0}; cFadeColor.alpha = uint16_t((1.0 - data.crossFadeProgress()) * 0xffff); if (cFadeAlpha == XCB_RENDER_PICTURE_NONE) { cFadeAlpha = xRenderFill(cFadeColor); } else { xcb_rectangle_t rect = {0, 0, 1, 1}; xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, cFadeAlpha, cFadeColor , 1, &rect); } if (previous->size() != pixmap->size()) { xcb_render_transform_t xform2 = { DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix11) * previous->size().width() / pixmap->size().width()), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix22) * previous->size().height() / pixmap->size().height()), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; xcb_render_set_picture_transform(connection(), previous->picture(), xform2); } xcb_render_composite(connection(), opaque ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_ATOP, previous->picture(), cFadeAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); if (previous->size() != pixmap->size()) { xcb_render_set_picture_transform(connection(), previous->picture(), identity); } } } if (!opaque) transformed_shape = QRegion(); } if (client || deleted) { if (!noBorder) { xcb_render_picture_t decorationAlpha = xRenderBlendPicture(data.opacity()); auto renderDeco = [decorationAlpha, renderTarget](xcb_render_picture_t deco, const QRect &rect) { if (deco == XCB_RENDER_PICTURE_NONE) { return; } xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, deco, decorationAlpha, renderTarget, 0, 0, 0, 0, rect.x(), rect.y(), rect.width(), rect.height()); }; renderDeco(top, dtr); renderDeco(left, dlr); renderDeco(right, drr); renderDeco(bottom, dbr); } } if (data.brightness() != 1.0) { // fake brightness change by overlaying black const float alpha = (1 - data.brightness()) * data.opacity(); xcb_rectangle_t rect; if (blitInTempPixmap) { rect.x = -temp_visibleRect.left(); rect.y = -temp_visibleRect.top(); rect.width = width(); rect.height = height(); } else { rect.x = wr.x(); rect.y = wr.y(); rect.width = wr.width(); rect.height = wr.height(); } xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_OVER, renderTarget, preMultiply(data.brightness() < 1.0 ? QColor(0,0,0,255*alpha) : QColor(255,255,255,-alpha*255)), 1, &rect); } if (blitInTempPixmap) { const QRect r = mapToScreen(mask, data, temp_visibleRect); xcb_render_set_picture_transform(connection(), *s_tempPicture, xform); setPictureFilter(*s_tempPicture, filter); xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, *s_tempPicture, XCB_RENDER_PICTURE_NONE, m_scene->bufferPicture(), 0, 0, 0, 0, r.x(), r.y(), r.width(), r.height()); xcb_render_set_picture_transform(connection(), *s_tempPicture, identity); } } if (scaled && !blitInTempPixmap) { xcb_render_set_picture_transform(connection(), pic, identity); if (filter == ImageFilterGood) setPictureFilter(pic, KWin::Scene::ImageFilterFast); if (!window()->hasAlpha()) { const uint32_t values[] = {XCB_RENDER_REPEAT_NONE}; xcb_render_change_picture(connection(), pic, XCB_RENDER_CP_REPEAT, values); } } if (xRenderOffscreen()) scene_setXRenderOffscreenTarget(*s_tempPicture); }
void RotateAndMoveBall(PObject * ObjectToMove) { /* Change the spin axis from X to Y or Y to X if requested by the user */ if (BallEvent & FLIP_SPIN_AXIS) { if (ObjectToMove->Rotate.RotateX != 0) { ObjectToMove->Rotate.RotateX = 0; ObjectToMove->Rotate.RotateY = 100; /* 10 degree Y rotations */ } else if (ObjectToMove->Rotate.RotateY != 0) { ObjectToMove->Rotate.RotateY = 0; ObjectToMove->Rotate.RotateZ = 50; /* 5 degree Z rotations */ } else { ObjectToMove->Rotate.RotateZ = 0; ObjectToMove->Rotate.RotateX = 75; /* 1.6 degree X rotations */ } BallEvent &= ~FLIP_SPIN_AXIS; } /* Rotate the ball as needed */ if (--ObjectToMove->RDelayCount == 0) { /* rotate */ ObjectToMove->RDelayCount = ObjectToMove->RDelayCountBase; if (ObjectToMove->Rotate.RotateX != 0) AppendRotationX(ObjectToMove->XformToWorld, ObjectToMove->Rotate.RotateX); if (ObjectToMove->Rotate.RotateY != 0) AppendRotationY(ObjectToMove->XformToWorld, ObjectToMove->Rotate.RotateY); if (ObjectToMove->Rotate.RotateZ != 0) AppendRotationZ(ObjectToMove->XformToWorld, ObjectToMove->Rotate.RotateZ); ObjectToMove->RecalcXform = 1; } /* Move the ball in response to recorded key events */ if (BallEvent & MOVE_LEFT) { if (ObjectToMove->XformToWorld[0][3] > DOUBLE_TO_FIXED(-15000.0)) { ObjectToMove->XformToWorld[0][3] -= DOUBLE_TO_FIXED(X_BALL_MOVE); ObjectToMove->RecalcXform = 1; } BallEvent &= ~MOVE_LEFT; } if (BallEvent & MOVE_RIGHT) { if (ObjectToMove->XformToWorld[0][3] < DOUBLE_TO_FIXED(15000.0)) { ObjectToMove->XformToWorld[0][3] += DOUBLE_TO_FIXED(X_BALL_MOVE); ObjectToMove->RecalcXform = 1; } BallEvent &= ~MOVE_RIGHT; } if (BallEvent & MOVE_UP) { if (ObjectToMove->XformToWorld[1][3] < DOUBLE_TO_FIXED(15000.0)) { ObjectToMove->XformToWorld[1][3] += DOUBLE_TO_FIXED(Y_BALL_MOVE); ObjectToMove->RecalcXform = 1; } BallEvent &= ~MOVE_UP; } if (BallEvent & MOVE_DOWN) { if (ObjectToMove->XformToWorld[1][3] > DOUBLE_TO_FIXED(-15000.0)) { ObjectToMove->XformToWorld[1][3] -= DOUBLE_TO_FIXED(Y_BALL_MOVE); ObjectToMove->RecalcXform = 1; } BallEvent &= ~MOVE_DOWN; } if (BallEvent & MOVE_TOWARD) { if (ObjectToMove->XformToWorld[2][3] < DOUBLE_TO_FIXED(-100.0)) { ObjectToMove->XformToWorld[2][3] += DOUBLE_TO_FIXED(Z_BALL_MOVE); ObjectToMove->RecalcXform = 1; } BallEvent &= ~MOVE_TOWARD; } if (BallEvent & MOVE_AWAY) { if (ObjectToMove->XformToWorld[2][3] > DOUBLE_TO_FIXED(-15000.0)) { ObjectToMove->XformToWorld[2][3] -= DOUBLE_TO_FIXED(Z_BALL_MOVE); ObjectToMove->RecalcXform = 1; } BallEvent &= ~MOVE_AWAY; } }
static BOOL CreateLUTS(LPMONITORPROFILERDATA sys, LPLUT* A2B, LPLUT* B2A) { LPLUT AToB0 = cmsAllocLUT(); LPLUT BToA0 = cmsAllocLUT(); LPGAMMATABLE LabG; cmsCIExyY xyY; cmsAlloc3DGrid(AToB0, sys->hdr.CLUTPoints, 3, 3); cmsAlloc3DGrid(BToA0, sys->hdr.CLUTPoints, 3, 3); /* cmsAllocLinearTable(AToB0, sys -> Prelinearization, 1); */ sys->ReverseTables[0] = cmsReverseGamma(4096, sys ->Prelinearization[0]); sys->ReverseTables[1] = cmsReverseGamma(4096, sys ->Prelinearization[1]); sys->ReverseTables[2] = cmsReverseGamma(4096, sys ->Prelinearization[2]); /* Prelinearization */ LabG = cmsBuildGamma(4096, 3.0); sys -> PreLab[0] = cmsJoinGammaEx(LabG, sys ->Prelinearization[0], 4096); sys -> PreLab[1] = cmsJoinGammaEx(LabG, sys ->Prelinearization[1], 4096); sys -> PreLab[2] = cmsJoinGammaEx(LabG, sys ->Prelinearization[2], 4096); sys -> PreLabRev[0] = cmsJoinGammaEx(sys ->Prelinearization[0], LabG, 4096); sys -> PreLabRev[1] = cmsJoinGammaEx(sys ->Prelinearization[1], LabG, 4096); sys -> PreLabRev[2] = cmsJoinGammaEx(sys ->Prelinearization[2], LabG, 4096); cmsFreeGamma(LabG); cmsAllocLinearTable(AToB0, sys->PreLabRev, 1); cmsAllocLinearTable(BToA0, sys->PreLab, 2); /* Set CIECAM97s parameters */ sys -> hdr.device.whitePoint.X = sys -> hdr.WhitePoint.X * 100.; sys -> hdr.device.whitePoint.Y = sys -> hdr.WhitePoint.Y * 100.; sys -> hdr.device.whitePoint.Z = sys -> hdr.WhitePoint.Z * 100.; /* Normalize White point for CIECAM97s model */ cmsXYZ2xyY(&xyY, &sys -> hdr.device.whitePoint); xyY.Y = 100.; cmsxyY2XYZ(&sys -> hdr.device.whitePoint, &xyY); sys->hdr.hDevice = cmsCIECAM97sInit(&sys->hdr.device); sys->hdr.hPCS = cmsCIECAM97sInit(&sys->hdr.PCS); cmsSample3DGrid(AToB0, RegressionSamplerA2B, sys, 0); cmsSample3DGrid(BToA0, RegressionSamplerB2A, sys, 0); cmsCIECAM97sDone(sys->hdr.hDevice); cmsCIECAM97sDone(sys->hdr.hPCS); cmsAddTag(sys->hdr.hProfile, icSigAToB0Tag, AToB0); cmsAddTag(sys->hdr.hProfile, icSigBToA0Tag, BToA0); /* This is the 0xff00 trick to map white at lattice point */ BToA0 ->Matrix.v[0].n[0] = DOUBLE_TO_FIXED((65535.0 / 65280.0)); *A2B = AToB0; *B2A = BToA0; cmsFreeGammaTriple(sys->ReverseTables); cmsFreeGammaTriple(sys->PreLab); cmsFreeGammaTriple(sys->PreLabRev); return true; }